1 ## @file
2 # @brief Implementation of a GOsa-SI event module.
3 # @details A GOsa-SI event module containing all functions to handle incoming messages from clients.
5 package clMessages;
6 use Exporter;
7 @ISA = qw(Exporter);
8 my @events = (
9 "confirm_usr_msg",
10 "PROGRESS",
11 "FAIREBOOT",
12 "TASKSKIP",
13 "TASKBEGIN",
14 "TASKEND",
15 "TASKERROR",
16 "HOOK",
17 "GOTOACTIVATION",
18 "LOGIN",
19 "LOGOUT",
20 "CURRENTLY_LOGGED_IN",
21 "save_fai_log",
22 );
23 @EXPORT = @events;
25 use strict;
26 use warnings;
27 use Data::Dumper;
28 use GOSA::GosaSupportDaemon;
29 use MIME::Base64;
32 BEGIN {}
34 END {}
37 ## @method get_events()
38 # @details A brief function returning a list of functions which are exported by importing the module.
39 # @return List of all provided functions
40 sub get_events {
41 return \@events;
42 }
44 ## @method confirm_usr_msg()
45 # @details Confirmed messages are set in the messaging_db from d (deliverd) to s(seen).
46 # @param msg - STRING - xml message with tags 'message', 'subject' and 'usr'
47 # @param msg_hash - HASHREF - message information parsed into a hash
48 # @param session_id - INTEGER - POE session id of the processing of this message
49 sub confirm_usr_msg {
50 my ($msg, $msg_hash, $session_id) = @_;
51 my $message = @{$msg_hash->{'message'}}[0];
52 my $subject = @{$msg_hash->{'subject'}}[0];
53 my $usr = @{$msg_hash->{'usr'}}[0];
55 # set update for this message
56 my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')";
57 &main::daemon_log("$session_id DEBUG: $sql", 7);
58 my $res = $main::messaging_db->exec_statement($sql);
61 return;
62 }
65 ## @method save_fai_log()
66 # @details Creates under /var/log/fai/ the directory '$macaddress' and stores within all FAI log files from client.
67 # @param msg - STRING - xml message with tags 'macaddress' and 'save_fai_log'
68 # @param msg_hash - HASHREF - message information parsed into a hash
69 # @param session_id - INTEGER - POE session id of the processing of this message
70 sub save_fai_log {
71 my ($msg, $msg_hash, $session_id) = @_;
72 my $header = @{$msg_hash->{'header'}}[0];
73 my $source = @{$msg_hash->{'source'}}[0];
74 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
75 my $all_logs = @{$msg_hash->{$header}}[0];
77 # if there is nothing to log
78 if( ref($all_logs) eq "HASH" ) { return; }
80 my $client_fai_log_dir = $main::client_fai_log_dir;
81 if (not -d $client_fai_log_dir) {
82 mkdir($client_fai_log_dir, 0755)
83 }
85 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
86 if (not -d $client_fai_log_dir) {
87 mkdir($client_fai_log_dir, 0755)
88 }
90 my $time = &get_time;
91 $time = substr($time, 0, 8)."_".substr($time, 8, 6);
92 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
93 mkdir($client_fai_log_dir, 0755);
95 my @all_logs = split(/log_file:/, $all_logs);
96 foreach my $log (@all_logs) {
97 if (length $log == 0) { next; };
98 my ($log_file, $log_string) = split(":", $log);
99 my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
101 open(my $LOG_FILE, ">$client_fai_log_file");
102 print $LOG_FILE &decode_base64($log_string);
103 close($LOG_FILE);
105 }
106 return;
107 }
109 ## @method LOGIN()
110 # @details Reported user from client is added to login_users_db.
111 # @param msg - STRING - xml message with tag 'LOGIN'
112 # @param msg_hash - HASHREF - message information parsed into a hash
113 # @param session_id - INTEGER - POE session id of the processing of this message
114 sub LOGIN {
115 my ($msg, $msg_hash, $session_id) = @_;
116 my $header = @{$msg_hash->{'header'}}[0];
117 my $source = @{$msg_hash->{'source'}}[0];
118 my $login = @{$msg_hash->{$header}}[0];
120 my %add_hash = ( table=>$main::login_users_tn,
121 primkey=> ['client', 'user'],
122 client=>$source,
123 user=>$login,
124 timestamp=>&get_time,
125 );
126 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
127 if ($res != 0) {
128 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
129 return;
130 }
132 return;
133 }
136 ## @method LOGOUT()
137 # @details Reported user from client is deleted from login_users_db.
138 # @param msg - STRING - xml message with tag 'LOGOUT'
139 # @param msg_hash - HASHREF - message information parsed into a hash
140 # @param session_id - INTEGER - POE session id of the processing of this message
141 sub LOGOUT {
142 my ($msg, $msg_hash, $session_id) = @_;
143 my $header = @{$msg_hash->{'header'}}[0];
144 my $source = @{$msg_hash->{'source'}}[0];
145 my $login = @{$msg_hash->{$header}}[0];
147 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')";
148 my $res = $main::login_users_db->del_dbentry($sql_statement);
149 &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5);
151 return;
152 }
155 ## @method CURRENTLY_LOGGED_IN()
156 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB.
157 # @param msg - STRING - xml message
158 # @param msg_hash - HASHREF - message information parsed into a hash
159 # @param session_id - INTEGER - POE session id of the processing of this message
160 sub CURRENTLY_LOGGED_IN {
161 my ($msg, $msg_hash, $session_id) = @_;
162 my ($sql_statement, $db_res);
163 my $header = @{$msg_hash->{'header'}}[0];
164 my $source = @{$msg_hash->{'source'}}[0];
165 my $login = @{$msg_hash->{$header}}[0];
167 if(ref $login eq "HASH") {
168 &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5);
169 return;
170 }
172 # Invoke set_last_system
173 my $res = &set_last_system($msg, $msg_hash, $session_id);
175 # fetch all user currently assigned to the client at login_users_db
176 my %currently_logged_in_user = ();
177 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
178 $db_res = $main::login_users_db->select_dbentry($sql_statement);
179 while( my($hit_id, $hit) = each(%{$db_res}) ) {
180 $currently_logged_in_user{$hit->{'user'}} = 1;
181 }
182 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
184 # update all reported users in login_user_db
185 my @logged_in_user = split(/\s+/, $login);
186 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
187 foreach my $user (@logged_in_user) {
188 my %add_hash = ( table=>$main::login_users_tn,
189 primkey=> ['client', 'user'],
190 client=>$source,
191 user=>$user,
192 timestamp=>&get_time,
193 );
194 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
195 if ($res != 0) {
196 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
197 return;
198 }
200 delete $currently_logged_in_user{$user};
201 }
203 # if there is still a user in %currently_logged_in_user
204 # although he is not reported by client
205 # then delete it from $login_user_db
206 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
207 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
208 "in at client '$source' but still found at login_user_db", 3);
209 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
210 my $res = $main::login_users_db->del_dbentry($sql_statement);
211 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
212 }
214 # Delete all users which logged in information is older than their logged_in_user_date_of_expiry
215 my $act_time = &get_time();
216 my $expiry_date = &calc_timestamp($act_time, "minus", $main::logged_in_user_date_of_expiry);
218 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE CAST(timestamp as UNSIGNED)<$expiry_date";
219 $db_res = $main::login_users_db->select_dbentry($sql_statement);
221 while( my($hit_id, $hit) = each(%{$db_res}) ) {
222 &main::daemon_log("$session_id INFO: user '".$hit->{'user'}."' is no longer reported to be logged in at host '".$hit->{'client'}."'", 5);
223 my $sql = "DELETE FROM $main::login_users_tn WHERE (client='".$hit->{'client'}."' AND user='".$hit->{'user'}."')";
224 my $res = $main::login_users_db->del_dbentry($sql);
225 &main::daemon_log("$session_id INFO: delete user '".$hit->{'user'}."' at client '".$hit->{'client'}."' from login_user_db", 5);
226 }
228 return;
229 }
232 ## @method set_last_system()
233 # @details Message set ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
234 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
235 # @param msg_hash - HASHREF - message information parsed into a hash
236 # @param session_id - INTEGER - POE session id of the processing of this message
237 sub set_last_system {
238 my ($msg, $msg_hash, $session_id) = @_;
239 my $header = @{$msg_hash->{'header'}}[0];
240 my $source = @{$msg_hash->{'source'}}[0];
241 my $login = @{$msg_hash->{$header}}[0];
243 # Sanity check of needed parameter
244 if (not exists $msg_hash->{'timestamp'}){
245 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
246 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
247 &main::daemon_log($msg, 1);
248 return;
249 }
250 if (@{$msg_hash->{'timestamp'}} != 1) {
251 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
252 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
253 &ymain::daemon_log($msg, 1);
254 return;
255 }
256 if (not exists $msg_hash->{'macaddress'}){
257 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
258 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
259 &main::daemon_log($msg, 1);
260 return;
261 }
262 if (@{$msg_hash->{'macaddress'}} != 1) {
263 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
264 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
265 &ymain::daemon_log($msg, 1);
266 return;
267 }
269 # Fetch needed parameter
270 my $mac = @{$msg_hash->{'macaddress'}}[0];
271 my $timestamp = @{$msg_hash->{'timestamp'}}[0];
273 # Prepare login list
274 my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
275 @login_list = &main::del_doubles(@login_list);
277 # Sanity check of login list
278 if (@login_list == 0) {
279 # TODO
280 return;
281 }
283 # Fetch ldap handle
284 my $ldap_handle = &main::get_ldap_handle();
286 # Get system info
287 my $ldap_mesg= $ldap_handle->search(
288 base => $main::ldap_base,
289 scope => 'sub',
290 filter => "macAddress=$mac",
291 );
292 if ($ldap_mesg->count == 0) {
293 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
294 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
295 return;
296 }
298 my $ldap_entry = $ldap_mesg->pop_entry();
299 my $system_dn = $ldap_entry->dn();
301 # For each logged in user set gotoLastSystem and gotoLastSystemLogin
302 foreach my $user (@login_list) {
303 # Search user
304 my $ldap_mesg= $ldap_handle->search(
305 base => $main::ldap_base,
306 scope => 'sub',
307 filter => "uid=$user",
308 );
309 # Sanity check of user search
310 if ($ldap_mesg->count == 0) {
311 &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
312 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
314 # Set gotoLastSystem and gotoLastSystemLogin
315 } else {
316 my $ldap_entry= $ldap_mesg->pop_entry();
317 my $do_update = 0;
319 # Set gotoLastSystem information
320 my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
321 if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
322 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
323 } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
324 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
325 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
326 $do_update++;
327 } else {
328 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
329 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
330 $do_update++;
331 }
333 # Set gotoLastSystemLogin information
334 # Attention: only write information if last_system_dn and system_dn differs
335 my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
336 if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
337 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
338 } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
339 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
340 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
341 $do_update++;
342 } else {
343 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
344 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
345 $do_update++;
346 }
348 if ($do_update) {
349 my $result = $ldap_entry->update($ldap_handle);
350 if ($result->code() != 0) {
351 &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
352 $result->{'errorMessage'}."\n".
353 "\tbase: $main::ldap_base\n".
354 "\tscope: 'sub'\n".
355 "\tfilter: 'uid=$user'\n".
356 "\tmessage: $msg", 1);
357 }
358 }
359 }
360 }
362 return;
363 }
366 ## @method GOTOACTIVATION()
367 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
368 # @param msg - STRING - xml message with tag 'macaddress'
369 # @param msg_hash - HASHREF - message information parsed into a hash
370 # @param session_id - INTEGER - POE session id of the processing of this message
371 sub GOTOACTIVATION {
372 my ($msg, $msg_hash, $session_id) = @_;
373 my $header = @{$msg_hash->{'header'}}[0];
374 my $source = @{$msg_hash->{'source'}}[0];
375 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
377 # test whether content is an empty hash or a string which is required
378 my $content = @{$msg_hash->{$header}}[0];
379 if(ref($content) eq "HASH") { $content = ""; }
381 # clean up header
382 $header =~ s/CLMSG_//g;
384 my $sql_statement = "UPDATE $main::job_queue_tn ".
385 "SET status='processing', progress='goto-activation', modified='1' ".
386 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
387 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
388 my $res = $main::job_db->update_dbentry($sql_statement);
389 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
390 return;
391 }
394 ## @method PROGRESS()
395 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
396 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
397 # @param msg_hash - HASHREF - message information parsed into a hash
398 # @param session_id - INTEGER - POE session id of the processing of this message
399 sub PROGRESS {
400 my ($msg, $msg_hash, $session_id) = @_;
401 my $header = @{$msg_hash->{'header'}}[0];
402 my $source = @{$msg_hash->{'source'}}[0];
403 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
405 # test whether content is an empty hash or a string which is required
406 my $content = @{$msg_hash->{$header}}[0];
407 if(ref($content) eq "HASH") { $content = ""; }
409 # clean up header
410 $header =~ s/CLMSG_//g;
412 my $sql_statement = "UPDATE $main::job_queue_tn ".
413 "SET progress='$content', modified='1' ".
414 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
415 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
416 my $res = $main::job_db->update_dbentry($sql_statement);
417 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
419 return;
420 }
423 ## @method FAIREBOOT()
424 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
425 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
426 # @param msg_hash - HASHREF - message information parsed into a hash
427 # @param session_id - INTEGER - POE session id of the processing of this message
428 sub FAIREBOOT {
429 my ($msg, $msg_hash, $session_id) = @_;
430 my $header = @{$msg_hash->{'header'}}[0];
431 my $source = @{$msg_hash->{'source'}}[0];
432 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
434 # test whether content is an empty hash or a string which is required
435 my $content = @{$msg_hash->{$header}}[0];
436 if(ref($content) eq "HASH") { $content = ""; }
438 # clean up header
439 $header =~ s/CLMSG_//g;
441 my $sql_statement = "UPDATE $main::job_queue_tn ".
442 "SET status='processing', result='$header "."$content', modified='1' ".
443 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
444 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
445 my $res = $main::job_db->update_dbentry($sql_statement);
446 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
448 return;
449 }
452 ## @method TASKSKIP()
453 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated.
454 # @param msg - STRING - xml message with tag 'macaddress'.
455 # @param msg_hash - HASHREF - message information parsed into a hash
456 # @param session_id - INTEGER - POE session id of the processing of this message
457 sub TASKSKIP {
458 my ($msg, $msg_hash, $session_id) = @_;
459 my $header = @{$msg_hash->{'header'}}[0];
460 my $source = @{$msg_hash->{'source'}}[0];
461 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
463 # test whether content is an empty hash or a string which is required
464 my $content = @{$msg_hash->{$header}}[0];
465 if(ref($content) eq "HASH") { $content = ""; }
467 # clean up header
468 $header =~ s/CLMSG_//g;
470 my $sql_statement = "UPDATE $main::job_queue_tn ".
471 "SET status='processing', result='$header "."$content', modified='1' ".
472 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
473 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
474 my $res = $main::job_db->update_dbentry($sql_statement);
475 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
477 return;
478 }
481 ## @method TASKBEGIN()
482 # @details Message reports a starting FAI task. If the task is equal to 'finish', 'faiend' or 'savelog', job at job_queue_db is being set to status 'done' and FAI state is being set to 'localboot'. If task is equal to 'chboot', 'test' or 'confdir', just do nothing. In all other cases, job at job_queue_db is going to be updated or created if not exists.
483 # @param msg - STRING - xml message with tag 'macaddress'.
484 # @param msg_hash - HASHREF - message information parsed into a hash
485 # @param session_id - INTEGER - POE session id of the processing of this message
486 sub TASKBEGIN {
487 my ($msg, $msg_hash, $session_id) = @_;
488 my $header = @{$msg_hash->{'header'}}[0];
489 my $source = @{$msg_hash->{'source'}}[0];
490 my $target = @{$msg_hash->{'target'}}[0];
491 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
493 # test whether content is an empty hash or a string which is required
494 my $content = @{$msg_hash->{$header}}[0];
495 if(ref($content) eq "HASH") { $content = ""; }
497 # clean up header
498 $header =~ s/CLMSG_//g;
500 # TASKBEGIN eq finish or faiend
501 if (($content eq 'finish')
502 || ($content eq 'faiend')
503 || ($content eq 'savelog')
504 ) {
505 my $sql_statement = "UPDATE $main::job_queue_tn ".
506 "SET status='done', result='$header "."$content', modified='1' ".
507 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
508 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
509 my $res = $main::job_db->update_dbentry($sql_statement);
510 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
512 # set fai_state to localboot
513 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
515 # TASKBEGIN eq chboot
516 } elsif (($content eq 'chboot')
517 || ($content eq 'test')
518 || ($content eq 'confdir')
519 ) {
520 # just ignor this client message
521 # do nothing
523 # other TASKBEGIN msgs
524 } else {
525 # select processing jobs for host
526 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
527 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
528 my $res = $main::job_db->select_dbentry($sql_statement);
530 # there is exactly one job entry in queue for this host
531 if (keys(%$res) == 1) {
532 &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
533 my $sql_statement = "UPDATE $main::job_queue_tn ".
534 "SET result='$header $content', modified='1', siserver='localhost' ".
535 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
536 my $err = $main::job_db->update_dbentry($sql_statement);
537 if (not defined $err) {
538 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
539 }
541 # there is no entry or more than one enties
542 } else {
543 # in case of more than one running jobs in queue, delete all jobs
544 if (keys(%$res) > 1) {
545 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
546 "delete entries", 7);
548 # set job to status 'done', job will be deleted automatically
549 my $sql_statement = "UPDATE $main::job_queue_tn ".
550 "SET status='done', modified='1'".
551 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
552 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
553 my $res = $main::job_db->update_dbentry( $sql_statement );
555 }
557 # in case of no and more than one running jobs in queue, add one single job
558 # resolve plain name for host $macaddress
559 my $plain_name;
560 my $ldap_handle = &main::get_ldap_handle($session_id);
561 if( not defined $ldap_handle ) {
562 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
563 $plain_name = "none";
565 # try to fetch a 'real name'
566 } else {
567 my $mesg = $ldap_handle->search(
568 base => $main::ldap_base,
569 scope => 'sub',
570 attrs => ['cn'],
571 filter => "(macAddress=$macaddress)");
572 if($mesg->code) {
573 &main::daemon_log($mesg->error, 1);
574 $plain_name = "none";
575 } else {
576 my $entry= $mesg->entry(0);
577 $plain_name = $entry->get_value("cn");
578 }
579 }
581 # In any case add a new job to job queue
582 &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7);
583 my $func_dic = {table=>$main::job_queue_tn,
584 primkey=>['macaddress', 'headertag'],
585 timestamp=>&get_time,
586 status=>'processing',
587 result=>"$header $content",
588 progress=>'none',
589 headertag=>'trigger_action_reinstall',
590 targettag=>$target,
591 xmlmessage=>'none',
592 macaddress=>$macaddress,
593 plainname=>$plain_name,
594 modified=>'1',
595 siserver=>'localhost',
596 };
597 my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
598 if ($err != 0) {
599 &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
600 }
601 }
602 }
604 return;
605 }
608 ## @method TASKEND()
609 # @details Message reports a finished FAI task. If task is equal to 'savelog', job at job_queue_db is going to be set to status 'done'. Otherwise, job is going to be updated.
610 # @param msg - STRING - xml message with tag 'macaddress'.
611 # @param msg_hash - HASHREF - message information parsed into a hash
612 # @param session_id - INTEGER - POE session id of the processing of this message
613 sub TASKEND {
614 my ($msg, $msg_hash, $session_id) = @_;
615 my $header = @{$msg_hash->{'header'}}[0];
616 my $target = @{$msg_hash->{'target'}}[0];
617 my $source = @{$msg_hash->{'source'}}[0];
618 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
620 # test whether content is an empty hash or a string which is required
621 my $content = @{$msg_hash->{$header}}[0];
622 if(ref($content) eq "HASH") { $content = ""; }
624 # clean up header
625 $header =~ s/CLMSG_//g;
627 if ($content eq "savelog 0") {
628 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
630 # set job to status 'done', job will be deleted automatically
631 my $sql_statement = "UPDATE $main::job_queue_tn ".
632 "SET status='done', modified='1'".
633 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
634 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
635 my $res = $main::job_db->update_dbentry( $sql_statement );
637 } else {
638 my $sql_statement = "UPDATE $main::job_queue_tn ".
639 "SET status='processing', result='$header "."$content', modified='1' ".
640 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
641 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
642 my $res = $main::job_db->update_dbentry($sql_statement);
643 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
644 }
646 return;
647 }
650 ## @method TASKERROR()
651 # @details Message reports a FAI error. Job at job_queue_db is going to be updated.
652 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
653 # @param msg_hash - HASHREF - message information parsed into a hash
654 # @param session_id - INTEGER - POE session id of the processing of this message
655 sub TASKERROR {
656 my ($msg, $msg_hash, $session_id) = @_;
657 my $header = @{$msg_hash->{'header'}}[0];
658 my $source = @{$msg_hash->{'source'}}[0];
659 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
661 # clean up header
662 $header =~ s/CLMSG_//g;
664 # test whether content is an empty hash or a string which is required
665 my $content = @{$msg_hash->{$header}}[0];
666 if(ref($content) eq "HASH") { $content = ""; }
668 # set fai_state to localboot
669 &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
671 my $sql_statement = "UPDATE $main::job_queue_tn ".
672 "SET status='processing', result='$header "."$content', modified='1' ".
673 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
674 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
675 my $res = $main::job_db->update_dbentry($sql_statement);
676 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
678 return;
679 }
682 ## @method HOOK()
683 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated.
684 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
685 # @param msg_hash - HASHREF - message information parsed into a hash
686 # @param session_id - INTEGER - POE session id of the processing of this message
687 sub HOOK {
688 my ($msg, $msg_hash, $session_id) = @_;
689 my $header = @{$msg_hash->{'header'}}[0];
690 my $source = @{$msg_hash->{'source'}}[0];
691 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
693 # clean up header
694 $header =~ s/CLMSG_//g;
696 # test whether content is an empty hash or a string which is required
697 my $content = @{$msg_hash->{$header}}[0];
698 if(not ref($content) eq "STRING") { $content = ""; }
700 my $sql_statement = "UPDATE $main::job_queue_tn ".
701 "SET status='processing', result='$header "."$content', modified='1' ".
702 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
703 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
704 my $res = $main::job_db->update_dbentry($sql_statement);
705 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
707 return;
708 }
711 =pod
713 =head1 NAME
715 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
717 =head1 SYNOPSIS
719 use GOSA::GosaSupportDaemon;
720 use MIME::Base64;
722 =head1 DESCRIPTION
724 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients.
726 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
728 =head1 METHODS
730 =over 4
732 =item get_events ( )
734 =item confirm_usr_msg ( )
736 =item PROGRESS ( )
738 =item FAIREBOOT ( )
740 =item TASKSKIP ( )
742 =item TASKBEGIN ( )
744 =item TASKEND ( )
746 =item TASKERROR ( )
748 =item HOOK ( )
750 =item GOTOACTIVATION ( )
752 =item LOGIN ( )
754 =item LOGOUT ( )
756 =item CURRENTLY_LOGGED_IN ( )
758 =item save_fai_log ( )
760 =back
762 =head1 BUGS
764 Please report any bugs, or post any suggestions, to the GOsa mailing list E<lt>gosa-devel@oss.gonicus.deE<gt> or to L<https://oss.gonicus.de/labs/gosa>
766 =head1 COPYRIGHT
768 This code is part of GOsa (L<http://www.gosa-project.org>)
770 Copyright (C) 2003-2008 GONICUS GmbH
772 This program is distributed in the hope that it will be useful,
773 but WITHOUT ANY WARRANTY; without even the implied warranty of
774 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
775 GNU General Public License for more details.
777 =cut
780 1;