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 "new_ping",
12 "network_completition",
13 "set_activated_for_installation",
14 "new_key_for_client",
15 "detect_hardware",
16 "get_login_usr",
17 "get_login_client",
18 "trigger_action_localboot",
19 "trigger_action_faireboot",
20 "trigger_action_reboot",
21 "trigger_action_activate",
22 "trigger_action_lock",
23 "trigger_action_halt",
24 "trigger_action_update",
25 "trigger_action_reinstall",
26 "trigger_action_memcheck",
27 "trigger_action_sysinfo",
28 "trigger_action_instant_update",
29 "trigger_action_rescan",
30 "trigger_action_wake",
31 "recreate_fai_server_db",
32 "recreate_fai_release_db",
33 "recreate_packages_list_db",
34 "send_user_msg",
35 "get_available_kernel",
36 "trigger_activate_new",
37 );
38 @EXPORT = @events;
40 use strict;
41 use warnings;
42 use GOSA::GosaSupportDaemon;
43 use Data::Dumper;
44 use Crypt::SmbHash;
45 use Net::ARP;
46 use Net::Ping;
47 use Socket;
48 use Time::HiRes qw( usleep);
50 BEGIN {}
52 END {}
54 ### Start ######################################################################
56 #&main::read_configfile($main::cfg_file, %cfg_defaults);
58 sub get_events {
59 return \@events;
60 }
62 sub send_user_msg {
64 # msg from gosa
65 # <xml><header>gosa_send_user_msg</header><source>GOSA</source><target>GOSA</target>
66 # <timestamp>20080429151605</timestamp>
67 # <users>andreas.rettenberger</users>
68 # <subject>hallo</subject>
69 # <message>test</message>
70 # <macaddress>GOSA</macaddress>
71 # </xml>
73 my ($msg, $msg_hash, $session_id) = @_ ;
74 my $header = @{$msg_hash->{'header'}}[0];
75 my $source = @{$msg_hash->{'source'}}[0];
76 my $target = @{$msg_hash->{'target'}}[0];
78 #my $subject = &decode_base64(@{$msg_hash->{'subject'}}[0]);
79 my $subject = @{$msg_hash->{'subject'}}[0];
80 my $from = @{$msg_hash->{'from'}}[0];
81 my @users = @{$msg_hash->{'users'}};
82 my @groups = @{$msg_hash->{'groups'}}[0];
83 my $delivery_time = @{$msg_hash->{'delivery_time'}}[0];
84 #my $message = &decode_base64(@{$msg_hash->{'message'}}[0]);
85 my $message = @{$msg_hash->{'message'}}[0];
87 # keep job queue uptodate if necessary
88 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
89 if( defined $jobdb_id) {
90 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
91 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
92 my $res = $main::job_db->exec_statement($sql_statement);
93 }
95 # error handling
96 if (not $delivery_time =~ /^\d{14}$/) {
97 my $error_string = "delivery_time '$delivery_time' is not a valid timestamp, please use format 'yyyymmddhhmmss'";
98 &main::daemon_log("$session_id ERROR: $error_string", 1);
99 return &create_xml_string(&create_xml_hash($header, $target, $source, $error_string));
100 }
102 # add incoming message to messaging_db
103 my $new_msg_id = 1;
104 my $new_msg_id_sql = "SELECT MAX(CAST(id AS INTEGER)) FROM $main::messaging_tn";
105 my $new_msg_id_res = $main::messaging_db->exec_statement($new_msg_id_sql);
106 if (defined @{@{$new_msg_id_res}[0]}[0] ) {
107 $new_msg_id = int(@{@{$new_msg_id_res}[0]}[0]);
108 $new_msg_id += 1;
109 }
111 # highlight user name and group name
112 my @receiver_l;
113 @users = map(push(@receiver_l, "u_$_"), @users);
114 #@groups = map(push(@receiver_l, "g_$_"), @groups);
115 # TODO
116 # handling, was passiert wenn in einer liste nix drin steht
117 # handling von groups hinzufügen
120 my $func_dic = {table=>$main::messaging_tn,
121 primkey=>[],
122 id=>$new_msg_id,
123 subject=>$subject,
124 message_from=>$from,
125 message_to=>join(",", @receiver_l),
126 flag=>"n",
127 direction=>"in",
128 delivery_time=>$delivery_time,
129 message=>$message,
130 timestamp=>&get_time(),
131 };
132 my $res = $main::messaging_db->add_dbentry($func_dic);
133 if (not $res == 0) {
134 &main::daemon_log("$session_id ERROR: gosaTriggered.pm: cannot add message to message_db: $res", 1);
135 } else {
136 &main::daemon_log("$session_id INFO: gosaTriggered.pm: message with subject '$subject' successfully added to message_db", 5);
137 }
139 return;
140 }
142 #sub send_user_msg_OLD {
143 # my ($msg, $msg_hash, $session_id) = @_ ;
144 # my @out_msg_l;
145 # my @user_list;
146 # my @group_list;
147 #
148 # my $header = @{$msg_hash->{'header'}}[0];
149 # my $source = @{$msg_hash->{'source'}}[0];
150 # my $target = @{$msg_hash->{'target'}}[0];
151 # my $message = @{$msg_hash->{'message'}}[0];
152 # if( exists $msg_hash->{'user'} ) { @user_list = @{$msg_hash->{'user'}}; }
153 # if( exists $msg_hash->{'group'} ) { @group_list = @{$msg_hash->{'group'}}; }
154 #
155 # my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
156 # if( defined $jobdb_id) {
157 # my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
158 # &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
159 # my $res = $main::job_db->exec_statement($sql_statement);
160 # }
161 #
162 # # error handling
163 # if( not @user_list && not @group_list ) {
164 # &main::daemon_log("$session_id WARNING: no user-tag or a group-tag specified in 'send_user_msg'", 3);
165 # return ("<xml><header>$header</header><source>GOSA</source><target>GOSA</target>".
166 # "<error_string>no user-tag or a group-tag specified in 'send_user_msg'</error_string></xml>");
167 # }
168 # if( not defined $message ) {
169 # &main::daemon_log("$session_id WARNING: no message-tag specified in 'send_user_msg'", 3);
170 # return ("<xml><header>$header</header><source>GOSA</source><target>GOSA</target>".
171 # "<error_string>no message-tag specified in 'send_user_msg'</error_string></xml>");
172 #
173 # }
174 #
175 # # resolve groups to users
176 # my $ldap_handle = &main::get_ldap_handle($session_id);
177 # if( @group_list ) {
178 # if( not defined $ldap_handle ) {
179 # &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
180 # return ();
181 # }
182 # foreach my $group (@group_list) { # Perform search
183 # my $mesg = $ldap_handle->search(
184 # base => $main::ldap_base,
185 # scope => 'sub',
186 # attrs => ['memberUid'],
187 # filter => "(&(objectClass=posixGroup)(cn=$group)(memberUid=*))");
188 # if($mesg->code) {
189 # &main::daemon_log($mesg->error, 1);
190 # return ();
191 # }
192 # my $entry= $mesg->entry(0);
193 # my @users= $entry->get_value("memberUid");
194 # foreach my $user (@users) { push(@user_list, $user); }
195 # }
196 # }
197 #
198 # # drop multiple users in @user_list
199 # my %seen = ();
200 # foreach my $user (@user_list) {
201 # $seen{$user}++;
202 # }
203 # @user_list = keys %seen;
204 #
205 # # build xml messages sended to client where user is logged in
206 # foreach my $user (@user_list) {
207 # my $sql_statement = "SELECT * FROM $main::login_users_tn WHERE user='$user'";
208 # my $db_res = $main::login_users_db->select_dbentry($sql_statement);
209 #
210 # if(0 == keys(%{$db_res})) {
211 #
212 # } else {
213 # while( my($hit, $content) = each %{$db_res} ) {
214 # my $out_hash = &create_xml_hash('send_user_msg', $main::server_address, $content->{'client'});
215 # &add_content2xml_hash($out_hash, 'message', $message);
216 # &add_content2xml_hash($out_hash, 'user', $user);
217 # if( exists $msg_hash->{'jobdb_id'} ) {
218 # &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]);
219 # }
220 # my $out_msg = &create_xml_string($out_hash);
221 # push(@out_msg_l, $out_msg);
222 # }
223 # }
224 # }
225 #
226 # return @out_msg_l;
227 #}
230 sub recreate_fai_server_db {
231 my ($msg, $msg_hash, $session_id) = @_ ;
232 my $out_msg;
234 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
235 if( defined $jobdb_id) {
236 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
237 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
238 my $res = $main::job_db->exec_statement($sql_statement);
239 }
241 $main::fai_server_db->create_table("new_fai_server", \@main::fai_server_col_names);
242 &main::create_fai_server_db("new_fai_server",undef,"dont", $session_id);
243 $main::fai_server_db->move_table("new_fai_server", $main::fai_server_tn);
245 my @out_msg_l = ( $out_msg );
246 return @out_msg_l;
247 }
250 sub recreate_fai_release_db {
251 my ($msg, $msg_hash, $session_id) = @_ ;
252 my $out_msg;
254 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
255 if( defined $jobdb_id) {
256 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
257 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
258 my $res = $main::job_db->exec_statement($sql_statement);
259 }
261 $main::fai_release_db->create_table("new_fai_release", \@main::fai_release_col_names);
262 &main::create_fai_release_db("new_fai_release", $session_id);
263 $main::fai_release_db->move_table("new_fai_release", $main::fai_release_tn);
265 my @out_msg_l = ( $out_msg );
266 return @out_msg_l;
267 }
270 sub recreate_packages_list_db {
271 my ($msg, $msg_hash, $session_id) = @_ ;
272 my $out_msg;
274 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
275 if( defined $jobdb_id) {
276 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
277 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
278 my $res = $main::job_db->exec_statement($sql_statement);
279 }
281 &main::create_packages_list_db;
283 my @out_msg_l = ( $out_msg );
284 return @out_msg_l;
285 }
288 sub get_login_usr_for_client {
289 my ($msg, $msg_hash, $session_id) = @_ ;
290 my $header = @{$msg_hash->{'header'}}[0];
291 my $source = @{$msg_hash->{'source'}}[0];
292 my $target = @{$msg_hash->{'target'}}[0];
293 my $client = @{$msg_hash->{'client'}}[0];
295 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
296 if( defined $jobdb_id) {
297 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
298 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
299 my $res = $main::job_db->exec_statement($sql_statement);
300 }
302 $header =~ s/^gosa_//;
304 my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$client' OR macaddress LIKE '$client'";
305 my $res = $main::known_clients_db->select_dbentry($sql_statement);
307 my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
308 $out_msg .= &db_res2xml($res);
309 $out_msg .= "</xml>";
311 my @out_msg_l = ( $out_msg );
312 return @out_msg_l;
313 }
316 sub get_client_for_login_usr {
317 my ($msg, $msg_hash, $session_id) = @_ ;
318 my $header = @{$msg_hash->{'header'}}[0];
319 my $source = @{$msg_hash->{'source'}}[0];
320 my $target = @{$msg_hash->{'target'}}[0];
322 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
323 if( defined $jobdb_id) {
324 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
325 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
326 my $res = $main::job_db->exec_statement($sql_statement);
327 }
329 my $usr = @{$msg_hash->{'usr'}}[0];
330 $header =~ s/^gosa_//;
332 my $sql_statement = "SELECT * FROM known_clients WHERE login LIKE '%$usr%'";
333 my $res = $main::known_clients_db->select_dbentry($sql_statement);
335 my $out_msg = "<xml><header>$header</header><source>$target</source><target>$source</target>";
336 $out_msg .= &db_res2xml($res);
337 $out_msg .= "</xml>";
338 my @out_msg_l = ( $out_msg );
339 return @out_msg_l;
341 }
344 sub ping {
345 my ($msg, $msg_hash, $session_id) = @_ ;
346 my $out_msg = $msg;
347 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
348 if( defined $jobdb_id) {
349 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
350 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
351 my $res = $main::job_db->exec_statement($sql_statement);
352 }
354 $out_msg =~ s/<header>gosa_/<header>/;
356 my @out_msg_l = ( $out_msg );
357 return @out_msg_l;
358 }
359 sub new_ping {
360 my ($msg, $msg_hash, $session_id) = @_ ;
361 my ($sql, $res);
362 my $out_msg = $msg;
363 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
364 if( defined $jobdb_id) {
365 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
366 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
367 my $res = $main::job_db->exec_statement($sql_statement);
368 }
370 $out_msg =~ s/<header>gosa_/<header>/;
372 # send message
373 my $header = @{$msg_hash->{header}}[0];
374 my $target = @{$msg_hash->{target}}[0];
376 $sql = "SELECT * FROM $main::known_clients_tn WHERE ((hostname='$target') || (macaddress LIKE '$target'))";
377 $res = $main::known_clients_db->exec_statement($sql);
378 my $host_name = @{@$res[0]}[0];
379 $out_msg =~ s/<target>\S+<\/target>/<target>$host_name<\/target>/;
380 $out_msg =~ s/<source>\S+<\/source>/<source>$main::server_address<\/source>/;
381 $out_msg =~ s/<\/xml>/<session_id>$session_id<\/session_id><\/xml>/;
382 my $host_key = @{@$res[0]}[2];
384 my $error = &main::send_msg_to_target($out_msg, $host_name, $host_key, $header, $session_id);
385 #if ($error != 0) {}
387 my $message_id;
388 while (1) {
389 $sql = "SELECT * FROM $main::incoming_tn WHERE headertag='answer_$session_id'";
390 $res = $main::incoming_db->exec_statement($sql);
391 if (ref @$res[0] eq "ARRAY") {
392 $message_id = @{@$res[0]}[0];
393 last;
394 }
395 usleep(100000);
396 }
397 my $answer_xml = @{@$res[0]}[3];
398 my %data = ( 'answer_xml' => 'bin noch da' );
399 my $answer_msg = &build_msg("got_new_ping", "$main::server_address", "GOSA", \%data);
401 $sql = "DELETE FROM $main::incoming_tn WHERE id=$message_id";
402 $res = $main::incoming_db->exec_statement($sql);
405 my @answer_msg_l = ( $answer_msg );
406 return @answer_msg_l;
407 }
411 sub gen_smb_hash {
412 my ($msg, $msg_hash, $session_id) = @_ ;
413 my $source = @{$msg_hash->{source}}[0];
414 my $target = @{$msg_hash->{target}}[0];
415 my $password = @{$msg_hash->{password}}[0];
417 my %data= ('hash' => join(q[:], ntlmgen $password));
418 my $out_msg = &build_msg("gen_smb_hash", $target, $source, \%data );
419 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
420 if (defined $forward_to_gosa) {
421 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
422 }
424 return ( $out_msg );
425 }
428 sub network_completition {
429 my ($msg, $msg_hash, $session_id) = @_ ;
430 my $source = @{$msg_hash->{source}}[0];
431 my $target = @{$msg_hash->{target}}[0];
432 my $name = @{$msg_hash->{hostname}}[0];
434 # Can we resolv the name?
435 my %data;
436 if (inet_aton($name)){
437 my $address = inet_ntoa(inet_aton($name));
438 my $p = Net::Ping->new('tcp');
439 my $mac= "";
440 if ($p->ping($address, 1)){
441 $mac = Net::ARP::arp_lookup("", $address);
442 }
444 %data= ('ip' => $address, 'mac' => $mac);
445 } else {
446 %data= ('ip' => '', 'mac' => '');
447 }
449 my $out_msg = &build_msg("network_completition", $target, $source, \%data );
450 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
451 if (defined $forward_to_gosa) {
452 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
453 }
455 return ( $out_msg );
456 }
459 sub detect_hardware {
460 my ($msg, $msg_hash, $session_id) = @_ ;
461 # just forward msg to client, but dont forget to split off 'gosa_' in header
462 my $source = @{$msg_hash->{source}}[0];
463 my $target = @{$msg_hash->{target}}[0];
464 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
465 if( defined $jobdb_id) {
466 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
467 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
468 my $res = $main::job_db->exec_statement($sql_statement);
469 }
471 my $out_hash = &create_xml_hash("detect_hardware", $source, $target);
472 if( defined $jobdb_id ) {
473 &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id);
474 }
475 my $out_msg = &create_xml_string($out_hash);
477 my @out_msg_l = ( $out_msg );
478 return @out_msg_l;
480 }
483 sub trigger_reload_ldap_config {
484 my ($msg, $msg_hash, $session_id) = @_ ;
485 my $target = @{$msg_hash->{target}}[0];
487 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
488 if( defined $jobdb_id) {
489 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
490 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
491 my $res = $main::job_db->exec_statement($sql_statement);
492 }
494 my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
495 my @out_msg_l = ( $out_msg );
497 return @out_msg_l;
498 }
501 sub set_activated_for_installation {
502 my ($msg, $msg_hash, $session_id) = @_;
503 my $header = @{$msg_hash->{header}}[0];
504 my $source = @{$msg_hash->{source}}[0];
505 my $target = @{$msg_hash->{target}}[0];
506 my @out_msg_l;
508 # update status of job
509 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
510 if( defined $jobdb_id) {
511 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
512 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
513 my $res = $main::job_db->exec_statement($sql_statement);
514 }
516 # create set_activated_for_installation message for delivery
517 my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $target);
518 if( defined $jobdb_id ) {
519 &add_content2xml_hash($out_hash, 'jobdb_id', $jobdb_id);
520 }
521 my $out_msg = &create_xml_string($out_hash);
522 push(@out_msg_l, $out_msg);
524 return @out_msg_l;
525 }
528 sub trigger_action_faireboot {
529 my ($msg, $msg_hash, $session_id) = @_;
530 my $macaddress = @{$msg_hash->{target}}[0];
531 my $source = @{$msg_hash->{source}}[0];
533 my @out_msg_l;
534 $msg =~ s/<header>gosa_trigger_action_faireboot<\/header>/<header>trigger_action_faireboot<\/header>/;
535 push(@out_msg_l, $msg);
537 &main::change_goto_state('locked', \@{$msg_hash->{target}}, $session_id);
538 &main::change_fai_state('install', \@{$msg_hash->{target}}, $session_id);
540 # delete all jobs from jobqueue which correspond to fai
541 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE (macaddress='$macaddress' AND ".
542 "status='processing')";
543 $main::job_db->del_dbentry($sql_statement );
545 return @out_msg_l;
546 }
549 sub trigger_action_lock {
550 my ($msg, $msg_hash, $session_id) = @_;
551 my $macaddress = @{$msg_hash->{target}}[0];
552 my $source = @{$msg_hash->{source}}[0];
554 &main::change_goto_state('locked', \@{$msg_hash->{target}}, $session_id);
555 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
556 if( defined $jobdb_id) {
557 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
558 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
559 my $res = $main::job_db->exec_statement($sql_statement);
560 }
562 my @out_msg_l;
563 return @out_msg_l;
564 }
567 sub trigger_action_activate {
568 my ($msg, $msg_hash, $session_id) = @_;
569 my $macaddress = @{$msg_hash->{target}}[0];
570 my $source = @{$msg_hash->{source}}[0];
572 &main::change_goto_state('active', \@{$msg_hash->{target}}, $session_id);
573 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
574 if( defined $jobdb_id) {
575 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
576 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
577 my $res = $main::job_db->exec_statement($sql_statement);
578 }
580 my $out_hash = &create_xml_hash("set_activated_for_installation", $source, $macaddress);
581 if( exists $msg_hash->{'jobdb_id'} ) {
582 &add_content2xml_hash($out_hash, 'jobdb_id', @{$msg_hash->{'jobdb_id'}}[0]);
583 }
584 my $out_msg = &create_xml_string($out_hash);
586 return ( $out_msg );
587 }
590 sub trigger_action_localboot {
591 my ($msg, $msg_hash, $session_id) = @_;
592 $msg =~ s/<header>gosa_trigger_action_localboot<\/header>/<header>trigger_action_localboot<\/header>/;
593 &main::change_fai_state('localboot', \@{$msg_hash->{target}}, $session_id);
594 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
595 if( defined $jobdb_id) {
596 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
597 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
598 my $res = $main::job_db->exec_statement($sql_statement);
599 }
601 my @out_msg_l = ($msg);
602 return @out_msg_l;
603 }
606 sub trigger_action_halt {
607 my ($msg, $msg_hash, $session_id) = @_;
608 $msg =~ s/<header>gosa_trigger_action_halt<\/header>/<header>trigger_action_halt<\/header>/;
610 &main::change_fai_state('halt', \@{$msg_hash->{target}}, $session_id);
611 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
612 if( defined $jobdb_id) {
613 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
614 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
615 my $res = $main::job_db->exec_statement($sql_statement);
616 }
618 my @out_msg_l = ($msg);
619 return @out_msg_l;
620 }
623 sub trigger_action_reboot {
624 my ($msg, $msg_hash, $session_id) = @_;
625 $msg =~ s/<header>gosa_trigger_action_reboot<\/header>/<header>trigger_action_reboot<\/header>/;
627 &main::change_fai_state('reboot', \@{$msg_hash->{target}}, $session_id);
628 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
629 if( defined $jobdb_id) {
630 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
631 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
632 my $res = $main::job_db->exec_statement($sql_statement);
633 }
635 my @out_msg_l = ($msg);
636 return @out_msg_l;
637 }
640 sub trigger_action_memcheck {
641 my ($msg, $msg_hash, $session_id) = @_ ;
642 $msg =~ s/<header>gosa_trigger_action_memcheck<\/header>/<header>trigger_action_memcheck<\/header>/;
644 &main::change_fai_state('memcheck', \@{$msg_hash->{target}}, $session_id);
645 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
646 if( defined $jobdb_id) {
647 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
648 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
649 my $res = $main::job_db->exec_statement($sql_statement);
650 }
652 my @out_msg_l = ($msg);
653 return @out_msg_l;
654 }
657 sub trigger_action_reinstall {
658 my ($msg, $msg_hash, $session_id) = @_;
659 $msg =~ s/<header>gosa_trigger_action_reinstall<\/header>/<header>trigger_action_reinstall<\/header>/;
661 &main::change_fai_state('reinstall', \@{$msg_hash->{target}}, $session_id);
663 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
664 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
665 my @out_msg_l = ($wake_msg, $msg);
666 return @out_msg_l;
667 }
670 sub trigger_action_update {
671 my ($msg, $msg_hash, $session_id) = @_;
672 $msg =~ s/<header>gosa_trigger_action_update<\/header>/<header>trigger_action_update<\/header>/;
674 &main::change_fai_state('update', \@{$msg_hash->{target}}, $session_id);
676 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
677 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
678 my @out_msg_l = ($wake_msg, $msg);
679 return @out_msg_l;
680 }
683 sub trigger_action_instant_update {
684 my ($msg, $msg_hash, $session_id) = @_;
685 $msg =~ s/<header>gosa_trigger_action_instant_update<\/header>/<header>trigger_action_instant_update<\/header>/;
687 &main::change_fai_state('update', \@{$msg_hash->{target}}, $session_id);
689 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
690 if( defined $jobdb_id) {
691 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
692 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
693 my $res = $main::job_db->exec_statement($sql_statement);
694 }
696 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
697 my $wake_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
698 my @out_msg_l = ($wake_msg, $msg);
699 return @out_msg_l;
700 }
703 sub trigger_action_sysinfo {
704 my ($msg, $msg_hash, $session_id) = @_;
705 $msg =~ s/<header>gosa_trigger_action_sysinfo<\/header>/<header>trigger_action_sysinfo<\/header>/;
707 &main::change_fai_state('sysinfo', \@{$msg_hash->{target}}, $session_id);
708 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
709 if( defined $jobdb_id) {
710 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
711 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
712 my $res = $main::job_db->exec_statement($sql_statement);
713 }
715 my @out_msg_l = ($msg);
716 return @out_msg_l;
717 }
720 sub new_key_for_client {
721 my ($msg, $msg_hash, $session_id) = @_;
723 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
724 if( defined $jobdb_id) {
725 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
726 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
727 my $res = $main::job_db->exec_statement($sql_statement);
728 }
730 $msg =~ s/<header>gosa_new_key_for_client<\/header>/<header>new_key<\/header>/;
731 my @out_msg_l = ($msg);
732 return @out_msg_l;
733 }
736 sub trigger_action_rescan {
737 my ($msg, $msg_hash, $session_id) = @_;
739 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
740 if( defined $jobdb_id) {
741 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
742 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
743 my $res = $main::job_db->exec_statement($sql_statement);
744 }
747 $msg =~ s/<header>gosa_trigger_action_rescan<\/header>/<header>trigger_action_rescan<\/header>/;
748 my @out_msg_l = ($msg);
749 return @out_msg_l;
750 }
753 sub trigger_action_wake {
754 my ($msg, $msg_hash, $session_id) = @_;
756 my $jobdb_id = @{$msg_hash->{'jobdb_id'}}[0];
757 if( defined $jobdb_id) {
758 my $sql_statement = "UPDATE $main::job_queue_tn SET status='processed' WHERE id=jobdb_id";
759 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
760 my $res = $main::job_db->exec_statement($sql_statement);
761 }
764 my %data = ( 'macAddress' => \@{$msg_hash->{target}} );
765 my $out_msg = &build_msg("trigger_wake", "GOSA", "KNOWN_SERVER", \%data);
766 my @out_msg_l = ($out_msg);
767 return @out_msg_l;
768 }
771 sub get_available_kernel {
772 my ($msg, $msg_hash, $session_id) = @_;
774 my $source = @{$msg_hash->{'source'}}[0];
775 my $target = @{$msg_hash->{'target'}}[0];
776 my $release= @{$msg_hash->{'release'}}[0];
778 my @kernel;
779 # Get Kernel packages for release
780 my $sql_statement = "SELECT * FROM $main::packages_list_tn WHERE distribution='$release' AND package LIKE 'linux\-image\-%'";
781 my $res_hash = $main::packages_list_db->select_dbentry($sql_statement);
782 my %data;
783 my $i=1;
785 foreach my $package (keys %{$res_hash}) {
786 $data{"answer".$i++}= $data{"answer".$i++}= ${$res_hash}{$package}->{'package'};
787 }
788 $data{"answer".$i++}= "default";
790 my $out_msg = &build_msg("get_available_kernel", $target, $source, \%data);
791 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
792 if (defined $forward_to_gosa) {
793 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
794 }
796 return ( $out_msg );
797 }
800 sub trigger_activate_new {
801 my ($msg, $msg_hash, $session_id) = @_;
803 my $source = @{$msg_hash->{'source'}}[0];
804 my $target = @{$msg_hash->{'target'}}[0];
805 my $header= @{$msg_hash->{'header'}}[0];
806 my $mac= (defined($msg_hash->{'mac'}))?@{$msg_hash->{'mac'}}[0]:undef;
807 my $ogroup= (defined($msg_hash->{'ogroup'}))?@{$msg_hash->{'ogroup'}}[0]:undef;
808 my $timestamp= (defined($msg_hash->{'timestamp'}))?@{$msg_hash->{'timestamp'}}[0]:undef;
809 my $base= (defined($msg_hash->{'base'}))?@{$msg_hash->{'base'}}[0]:undef;
810 my $hostname= (defined($msg_hash->{'fqdn'}))?@{$msg_hash->{'fqdn'}}[0]:undef;
811 my $ip_address= (defined($msg_hash->{'ip'}))?@{$msg_hash->{'ip'}}[0]:undef;
812 my $dhcp_statement= (defined($msg_hash->{'dhcp'}))?@{$msg_hash->{'dhcp'}}[0]:undef;
813 my $jobdb_id= (defined($msg_hash->{'jobdb_id'}))?@{$msg_hash->{'jobdb_id'}}[0]:undef;
815 my $ldap_handle = &main::get_ldap_handle();
816 my $ldap_entry;
817 my $ogroup_entry;
819 # build the base, use optional base parameter or take it from ogroup
820 if(!(defined($base) && (length($base) > 0))) {
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();
829 # Subtract the ObjectGroup cn
830 $base = $1 if $ogroup_entry->dn =~ /cn=$ogroup,ou=groups,(.*)$/;
831 } elsif ($ldap_mesg->count == 0) {
832 &main::daemon_log("ERROR: A GosaGroupOfNames with cn '$ogroup' was not found in base '".$main::ldap_base."'!", 1);
833 } else {
834 &main::daemon_log("ERROR: More than one ObjectGroups with cn '$ogroup' was found in base '".$main::ldap_base."'!", 1);
835 }
836 }
838 # prepend ou=systems
839 $base = "ou=systems,".$base;
841 # Search for an existing entry (should be in ou=incoming)
842 my $ldap_mesg= $ldap_handle->search(
843 base => $main::ldap_base,
844 scope => 'sub',
845 filter => "(&(objectClass=GOhard)(|(macAddress=$mac)(dhcpHWaddress=$mac)))",
846 );
848 # TODO: Find a way to guess an ip address for hosts with no ldap entry (MAC->ARP->IP)
850 if($ldap_mesg->count == 1) {
851 &main::daemon_log("NOTICE: One system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
852 # Get the entry from LDAP
853 $ldap_entry= $ldap_mesg->pop_entry();
855 if(!($ldap_entry->dn() eq "cn=".$ldap_entry->get_value('cn').",$base")) {
856 # Move the entry to the new ou
857 $ldap_entry->changetype('moddn');
858 $ldap_entry->add(
859 'newrdn' => "cn=".$ldap_entry->get_value('cn'),
860 'deleteoldrdn' => "1",
861 'newsuperior' => $base,
862 );
863 my $mesg = $ldap_entry->update($ldap_handle);
864 if($mesg->code() != 0) {
865 &main::daemon_log("ERROR: Updating the dn for system with mac address '$mac' failed (code ".$mesg->code().") with '".$mesg->{'errorMessage'}."'!", 1);
866 }
867 }
868 # Check for needed objectClasses
869 my $oclasses = $ldap_entry->get_value('objectClass', asref => 1);
870 foreach my $oclass ("FAIobject", "GOhard") {
871 if(!(scalar grep $_ eq $oclass, map {$_ => 1} @$oclasses)) {
872 $ldap_entry->add(
873 objectClass => $oclass,
874 );
875 }
876 }
878 # Set FAIstate
879 if(defined($ldap_entry->get_value('FAIstate'))) {
880 if(!($ldap_entry->get_value('FAIstate') eq 'install')) {
881 $ldap_entry->replace(
882 'FAIstate' => 'install'
883 );
884 my $faistate_mesg = $ldap_entry->update($ldap_handle);
885 if ($faistate_mesg->code() != 0) {
886 &main::daemon_log("ERROR: Updating the FAIstate for '".$ldap_entry->dn()."' failed (code '".$faistate_mesg->code()."') with '$@'!", 1);
887 }
888 }
889 } else {
890 $ldap_entry->add(
891 'FAIstate' => 'install'
892 );
893 my $faistate_mesg = $ldap_entry->update($ldap_handle);
894 if ($faistate_mesg->code() != 0) {
895 &main::daemon_log("ERROR: Updating the FAIstate for '".$ldap_entry->dn()."' failed (code '".$faistate_mesg->code()."') with '$@'!", 1);
896 }
897 }
900 } elsif ($ldap_mesg->count == 0) {
901 # TODO: Create a new entry
902 # $ldap_entry = Net::LDAP::Entry->new();
903 # $ldap_entry->dn("cn=$mac,$base");
904 &main::daemon_log("WARNING: No System with mac address '$mac' was found in base '".$main::ldap_base."'! Re-queuing job.", 4);
905 $main::job_db->select_dbentry("UPDATE jobs SET state = 'waiting', timestamp = '".&get_time()."' WHERE header = 'trigger_activate_new' AND mac_address LIKE '$mac'");
906 } else {
907 &main::daemon_log("ERROR: More than one system with mac address '$mac' was found in base '".$main::ldap_base."'!", 1);
908 }
910 my $update_mesg = $ldap_entry->update($ldap_handle);
911 if ($update_mesg->code() != 0) {
912 &main::daemon_log("ERROR: Updating attributes for '".$ldap_entry->dn()."' failed (code '".$update_mesg->code()."') with '".$update_mesg->{'errorMessage'}."'!", 1);
913 }
915 # Add to ObjectGroup
916 if(!(scalar grep $_, map {$_ => 1} $ogroup_entry->get_value('member', asref => 1))) {
917 $ogroup_entry->add (
918 'member' => $ldap_entry->dn(),
919 );
920 my $ogroup_result = $ogroup_entry->update($ldap_handle);
921 if ($ogroup_result->code() != 0) {
922 &main::daemon_log("ERROR: Updating the ObjectGroup '$ogroup' failed (code '".$ogroup_result->code()."') with '".$ogroup_result->{'errorMessage'}."'!", 1);
923 }
924 }
926 # Finally set gotoMode to active
927 if(defined($ldap_entry->get_value('gotoMode'))) {
928 if(!($ldap_entry->get_value('gotoMode') eq 'active')) {
929 $ldap_entry->replace(
930 'gotoMode' => 'active'
931 );
932 }
933 } else {
934 $ldap_entry->add(
935 'gotoMode' => 'active'
936 );
937 }
938 my $activate_result = $ldap_entry->update($ldap_handle);
939 if ($activate_result->code() != 0) {
940 &main::daemon_log("ERROR: Activating system '".$ldap_entry->dn()."' failed (code '".$activate_result->code()."') with '".$activate_result->{'errorMessage'}."'!", 1);
941 }
944 my %data;
945 my $out_msg = &build_msg("activate_new", $target, $source, \%data);
946 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
947 if (defined $forward_to_gosa) {
948 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
949 }
951 return ( $out_msg );
952 }
955 1;