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 $fai_action = @{$msg_hash->{'fai_action'}}[0];
76 my $all_logs = @{$msg_hash->{$header}}[0];
78 # if there is nothing to log
79 if( ref($all_logs) eq "HASH" ) {
80 &main::daemon_log("$session_id INFO: There is nothing to log!", 5);
81 return;
82 }
84 my $client_fai_log_dir = $main::client_fai_log_dir;
85 if (not -d $client_fai_log_dir) {
86 mkdir($client_fai_log_dir, 0755)
87 }
89 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
90 if (not -d $client_fai_log_dir) {
91 mkdir($client_fai_log_dir, 0755)
92 }
94 my $time = &get_time;
95 $time = substr($time, 0, 8)."_".substr($time, 8, 6);
96 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $fai_action ."_".$time );
97 mkdir($client_fai_log_dir, 0755);
99 my @all_logs = split(/log_file:/, $all_logs);
100 foreach my $log (@all_logs) {
101 if (length $log == 0) { next; };
102 my ($log_file, $log_string) = split(":", $log);
103 my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
105 open(my $LOG_FILE, ">$client_fai_log_file");
106 print $LOG_FILE &decode_base64($log_string);
107 close($LOG_FILE);
108 chown($main::root_uid, $main::adm_gid, $client_fai_log_file);
109 chmod(0440, $client_fai_log_file);
111 }
112 return;
113 }
115 ## @method LOGIN()
116 # @details Reported user from client is added to login_users_db.
117 # @param msg - STRING - xml message with tag 'LOGIN'
118 # @param msg_hash - HASHREF - message information parsed into a hash
119 # @param session_id - INTEGER - POE session id of the processing of this message
120 sub LOGIN {
121 my ($msg, $msg_hash, $session_id) = @_;
122 my $header = @{$msg_hash->{'header'}}[0];
123 my $source = @{$msg_hash->{'source'}}[0];
124 my $login = @{$msg_hash->{$header}}[0];
125 my $res;
126 my $error_str;
128 # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
129 # &set_last_system($msg, $msg_hash, $session_id);
131 # Add user to login_users_db
132 my %add_hash = ( table=>$main::login_users_tn,
133 primkey=> ['client', 'user'],
134 client=>$source,
135 user=>$login,
136 timestamp=>&get_time,
137 regserver=>'localhost',
138 );
139 ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
140 if ($res != 0) {
141 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
142 return;
143 }
145 # Share login information with all other si-server
146 my %data = ( 'new_user' => "$source;$login" );
147 my $info_msg = &build_msg("information_sharing", $main::server_address, "KNOWN_SERVER", \%data);
149 return ($info_msg);
150 }
153 ## @method LOGOUT()
154 # @details Reported user from client is deleted from login_users_db.
155 # @param msg - STRING - xml message with tag 'LOGOUT'
156 # @param msg_hash - HASHREF - message information parsed into a hash
157 # @param session_id - INTEGER - POE session id of the processing of this message
158 sub LOGOUT {
159 my ($msg, $msg_hash, $session_id) = @_;
160 my $header = @{$msg_hash->{'header'}}[0];
161 my $source = @{$msg_hash->{'source'}}[0];
162 my $login = @{$msg_hash->{$header}}[0];
164 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')";
165 my $res = $main::login_users_db->del_dbentry($sql_statement);
166 &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5);
168 return;
169 }
172 ## @method CURRENTLY_LOGGED_IN()
173 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB.
174 # @param msg - STRING - xml message
175 # @param msg_hash - HASHREF - message information parsed into a hash
176 # @param session_id - INTEGER - POE session id of the processing of this message
177 sub CURRENTLY_LOGGED_IN {
178 my ($msg, $msg_hash, $session_id) = @_;
179 my ($sql_statement, $db_res);
180 my $header = @{$msg_hash->{'header'}}[0];
181 my $source = @{$msg_hash->{'source'}}[0];
182 my $login = @{$msg_hash->{$header}}[0];
184 if(ref $login eq "HASH") {
185 &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5);
186 return;
187 }
189 # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
190 # &set_last_system($msg, $msg_hash, $session_id);
192 # fetch all user currently assigned to the client at login_users_db
193 my %currently_logged_in_user = ();
194 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
195 $db_res = $main::login_users_db->select_dbentry($sql_statement);
196 while( my($hit_id, $hit) = each(%{$db_res}) ) {
197 $currently_logged_in_user{$hit->{'user'}} = 1;
198 }
199 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
201 # update all reported users in login_user_db
202 my @logged_in_user = split(/\s+/, $login);
203 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
204 foreach my $user (@logged_in_user) {
205 my %add_hash = ( table=>$main::login_users_tn,
206 primkey=> ['client', 'user'],
207 client=>$source,
208 user=>$user,
209 timestamp=>&get_time,
210 regserver=>'localhost',
211 );
212 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
213 if ($res != 0) {
214 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
215 return;
216 }
218 delete $currently_logged_in_user{$user};
219 }
221 # if there is still a user in %currently_logged_in_user
222 # although he is not reported by client
223 # then delete it from $login_user_db
224 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
225 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
226 "in at client '$source' but still found at login_user_db", 3);
227 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
228 my $res = $main::login_users_db->del_dbentry($sql_statement);
229 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
230 }
232 # Delete all users which logged in information is older than their logged_in_user_date_of_expiry
233 my $act_time = &get_time();
234 my $expiry_date = &calc_timestamp($act_time, "minus", $main::logged_in_user_date_of_expiry);
236 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE CAST(timestamp as UNSIGNED)<$expiry_date";
237 $db_res = $main::login_users_db->select_dbentry($sql_statement);
239 while( my($hit_id, $hit) = each(%{$db_res}) ) {
240 &main::daemon_log("$session_id INFO: user '".$hit->{'user'}."' is no longer reported to be logged in at host '".$hit->{'client'}."'", 5);
241 my $sql = "DELETE FROM $main::login_users_tn WHERE (client='".$hit->{'client'}."' AND user='".$hit->{'user'}."')";
242 my $res = $main::login_users_db->del_dbentry($sql);
243 &main::daemon_log("$session_id INFO: delete user '".$hit->{'user'}."' at client '".$hit->{'client'}."' from login_user_db", 5);
244 }
246 # Inform all other server which users are logged in at clients registered at local server
247 my $info_sql = "SELECT * FROM $main::login_users_tn WHERE regserver='localhost'";
248 my $info_res = $main::login_users_db->select_dbentry($info_sql);
249 my $info_msg_hash = &create_xml_hash("information_sharing", $main::server_address, "KNOWN_SERVER");
250 while (my ($hit_id, $hit) = each(%$info_res)) {
251 &add_content2xml_hash($info_msg_hash, 'user_db', $hit->{'client'}.";".$hit->{'user'});
252 }
253 my $info_msg = &create_xml_string($info_msg_hash);
255 return ($info_msg);
256 }
259 ## @method set_last_system()
260 # @details Message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
261 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
262 # @param msg_hash - HASHREF - message information parsed into a hash
263 # @param session_id - INTEGER - POE session id of the processing of this message
264 sub set_last_system {
265 my ($msg, $msg_hash, $session_id) = @_;
266 my $header = @{$msg_hash->{'header'}}[0];
267 my $source = @{$msg_hash->{'source'}}[0];
268 my $login = @{$msg_hash->{$header}}[0];
270 # Sanity check of needed parameter
271 if (not exists $msg_hash->{'timestamp'}){
272 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
273 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
274 &main::daemon_log($msg, 1);
275 return;
276 }
277 if (@{$msg_hash->{'timestamp'}} != 1) {
278 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
279 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
280 &ymain::daemon_log($msg, 1);
281 return;
282 }
283 if (not exists $msg_hash->{'macaddress'}){
284 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
285 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
286 &main::daemon_log($msg, 1);
287 return;
288 }
289 if (@{$msg_hash->{'macaddress'}} != 1) {
290 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
291 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
292 &ymain::daemon_log($msg, 1);
293 return;
294 }
296 # Fetch needed parameter
297 my $mac = @{$msg_hash->{'macaddress'}}[0];
298 my $timestamp = @{$msg_hash->{'timestamp'}}[0];
300 # Prepare login list
301 my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
302 @login_list = &main::del_doubles(@login_list);
304 # Sanity check of login list
305 if (@login_list == 0) {
306 # TODO
307 return;
308 }
310 # Fetch ldap handle
311 my $ldap_handle = &main::get_ldap_handle();
313 # Get system info
314 my $ldap_mesg= $ldap_handle->search(
315 base => $main::ldap_base,
316 scope => 'sub',
317 filter => "macAddress=$mac",
318 );
319 if ($ldap_mesg->count == 0) {
320 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
321 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
322 return;
323 }
325 my $ldap_entry = $ldap_mesg->pop_entry();
326 my $system_dn = $ldap_entry->dn();
328 # For each logged in user set gotoLastSystem and gotoLastSystemLogin
329 foreach my $user (@login_list) {
330 # Search user
331 my $ldap_mesg= $ldap_handle->search(
332 base => $main::ldap_base,
333 scope => 'sub',
334 filter => "uid=$user",
335 );
336 # Sanity check of user search
337 if ($ldap_mesg->count == 0) {
338 &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
339 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
341 # Set gotoLastSystem and gotoLastSystemLogin
342 } else {
343 my $ldap_entry= $ldap_mesg->pop_entry();
344 my $do_update = 0;
346 # Set gotoLastSystem information
347 my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
348 if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
349 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
350 } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
351 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
352 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
353 $do_update++;
354 } else {
355 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
356 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
357 $do_update++;
358 }
360 # Set gotoLastSystemLogin information
361 # Attention: only write information if last_system_dn and system_dn differs
362 my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
363 if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
364 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
365 } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
366 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
367 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
368 $do_update++;
369 } else {
370 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
371 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
372 $do_update++;
373 }
375 if ($do_update) {
376 my $result = $ldap_entry->update($ldap_handle);
377 if ($result->code() != 0) {
378 &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
379 $result->{'errorMessage'}."\n".
380 "\tbase: $main::ldap_base\n".
381 "\tscope: 'sub'\n".
382 "\tfilter: 'uid=$user'\n".
383 "\tmessage: $msg", 1);
384 }
385 }
386 }
387 }
389 return;
390 }
393 ## @method GOTOACTIVATION()
394 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
395 # @param msg - STRING - xml message with tag 'macaddress'
396 # @param msg_hash - HASHREF - message information parsed into a hash
397 # @param session_id - INTEGER - POE session id of the processing of this message
398 sub GOTOACTIVATION {
399 my ($msg, $msg_hash, $session_id) = @_;
400 my $header = @{$msg_hash->{'header'}}[0];
401 my $source = @{$msg_hash->{'source'}}[0];
402 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
404 # test whether content is an empty hash or a string which is required
405 my $content = @{$msg_hash->{$header}}[0];
406 if(ref($content) eq "HASH") { $content = ""; }
408 # clean up header
409 $header =~ s/CLMSG_//g;
411 my $sql_statement = "UPDATE $main::job_queue_tn ".
412 "SET progress='goto-activation', modified='1' ".
413 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
414 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
415 my $res = $main::job_db->update_dbentry($sql_statement);
416 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
417 return;
418 }
421 ## @method PROGRESS()
422 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
423 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
424 # @param msg_hash - HASHREF - message information parsed into a hash
425 # @param session_id - INTEGER - POE session id of the processing of this message
426 sub PROGRESS {
427 my ($msg, $msg_hash, $session_id) = @_;
428 my $header = @{$msg_hash->{'header'}}[0];
429 my $source = @{$msg_hash->{'source'}}[0];
430 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
432 # test whether content is an empty hash or a string which is required
433 my $content = @{$msg_hash->{$header}}[0];
434 if(ref($content) eq "HASH") { $content = ""; }
436 # clean up header
437 $header =~ s/CLMSG_//g;
439 my $sql_statement = "UPDATE $main::job_queue_tn ".
440 "SET progress='$content', modified='1' ".
441 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
442 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
443 my $res = $main::job_db->update_dbentry($sql_statement);
444 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
446 return;
447 }
450 ## @method FAIREBOOT()
451 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
452 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
453 # @param msg_hash - HASHREF - message information parsed into a hash
454 # @param session_id - INTEGER - POE session id of the processing of this message
455 sub FAIREBOOT {
456 my ($msg, $msg_hash, $session_id) = @_;
457 my $header = @{$msg_hash->{'header'}}[0];
458 my $source = @{$msg_hash->{'source'}}[0];
459 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
461 # test whether content is an empty hash or a string which is required
462 my $content = @{$msg_hash->{$header}}[0];
463 if(ref($content) eq "HASH") { $content = ""; }
465 # clean up header
466 $header =~ s/CLMSG_//g;
468 my $sql_statement = "UPDATE $main::job_queue_tn ".
469 "SET result='$header "."$content', modified='1' ".
470 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
471 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
472 my $res = $main::job_db->update_dbentry($sql_statement);
473 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
475 return;
476 }
479 ## @method TASKSKIP()
480 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated.
481 # @param msg - STRING - xml message with tag 'macaddress'.
482 # @param msg_hash - HASHREF - message information parsed into a hash
483 # @param session_id - INTEGER - POE session id of the processing of this message
484 sub TASKSKIP {
485 my ($msg, $msg_hash, $session_id) = @_;
486 my $header = @{$msg_hash->{'header'}}[0];
487 my $source = @{$msg_hash->{'source'}}[0];
488 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
490 # test whether content is an empty hash or a string which is required
491 my $content = @{$msg_hash->{$header}}[0];
492 if(ref($content) eq "HASH") { $content = ""; }
494 # clean up header
495 $header =~ s/CLMSG_//g;
497 my $sql_statement = "UPDATE $main::job_queue_tn ".
498 "SET result='$header "."$content', modified='1' ".
499 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
500 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
501 my $res = $main::job_db->update_dbentry($sql_statement);
502 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
504 return;
505 }
508 ## @method TASKBEGIN()
509 # @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', 'tests' or 'confdir', just do nothing. In all other cases, job at job_queue_db is going to be updated or created if not exists.
510 # @param msg - STRING - xml message with tag 'macaddress'.
511 # @param msg_hash - HASHREF - message information parsed into a hash
512 # @param session_id - INTEGER - POE session id of the processing of this message
513 sub TASKBEGIN {
514 my ($msg, $msg_hash, $session_id) = @_;
515 my $header = @{$msg_hash->{'header'}}[0];
516 my $source = @{$msg_hash->{'source'}}[0];
517 my $target = @{$msg_hash->{'target'}}[0];
518 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
520 # test whether content is an empty hash or a string which is required
521 my $content = @{$msg_hash->{$header}}[0];
522 if(ref($content) eq "HASH") { $content = ""; }
524 # clean up header
525 $header =~ s/CLMSG_//g;
527 # TASKBEGIN eq finish or faiend
528 if (($content eq 'finish')
529 || ($content eq 'faiend')
530 || ($content eq 'savelog')
531 ) {
532 my $sql_statement = "UPDATE $main::job_queue_tn ".
533 "SET status='done', result='$header "."$content', modified='1' ".
534 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
535 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
536 my $res = $main::job_db->update_dbentry($sql_statement);
537 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
539 # set fai_state to localboot
540 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
542 # TASKBEGIN eq chboot
543 } elsif (($content eq 'chboot')
544 || ($content eq 'tests')
545 || ($content eq 'confdir')
546 ) {
547 # just ignor this client message
548 # do nothing
550 # other TASKBEGIN msgs
551 } else {
553 # TASKBEGIN msgs do only occour during a softupdate or a reinstallation
554 # of a host. Set all waiting update- or reinstall-jobs for host to
555 # processing so they can be handled correctly by the rest of the function.
556 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
557 my $waiting_sql = "UPDATE $main::job_queue_tn SET status='processing' WHERE status='waiting' AND macaddress LIKE '$macaddress' AND (headertag='trigger_action_update' OR headertag='trigger_action_reinstall')";
558 &main::daemon_log("$session_id DEBUB: $waiting_sql", 7);
559 my $waiting_res = $main::job_db->update_dbentry($waiting_sql);
561 # select processing jobs for host
562 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
563 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
564 my $res = $main::job_db->select_dbentry($sql_statement);
566 # there is exactly one job entry in queue for this host
567 if (keys(%$res) == 1) {
568 &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
569 my $sql_statement = "UPDATE $main::job_queue_tn ".
570 "SET result='$header $content', modified='1', siserver='localhost' ".
571 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
572 my $err = $main::job_db->update_dbentry($sql_statement);
573 if (not defined $err) {
574 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
575 }
577 # there is no entry or more than one enties
578 } else {
579 # in case of more than one running jobs in queue, delete all jobs
580 if (keys(%$res) > 1) {
581 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
582 "delete entries", 7);
584 # set job to status 'done', job will be deleted automatically
585 my $sql_statement = "UPDATE $main::job_queue_tn ".
586 "SET status='done', modified='1'".
587 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
588 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
589 my $res = $main::job_db->update_dbentry( $sql_statement );
591 }
593 # in case of no and more than one running jobs in queue, add one single job
594 # resolve plain name for host $macaddress
595 my $plain_name;
596 my $ldap_handle = &main::get_ldap_handle($session_id);
597 if( not defined $ldap_handle ) {
598 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
599 $plain_name = "none";
601 # try to fetch a 'real name'
602 } else {
603 my $mesg = $ldap_handle->search(
604 base => $main::ldap_base,
605 scope => 'sub',
606 attrs => ['cn'],
607 filter => "(macAddress=$macaddress)");
608 if($mesg->code) {
609 &main::daemon_log($mesg->error, 1);
610 $plain_name = "none";
611 } else {
612 my $entry= $mesg->entry(0);
613 $plain_name = $entry->get_value("cn");
614 }
615 }
617 # In any case add a new job to job queue
618 &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7);
619 my $func_dic = {table=>$main::job_queue_tn,
620 primkey=>['macaddress', 'headertag'],
621 timestamp=>&get_time,
622 status=>'processing',
623 result=>"$header $content",
624 progress=>'none',
625 headertag=>'trigger_action_reinstall',
626 targettag=>$target,
627 xmlmessage=>'none',
628 macaddress=>$macaddress,
629 plainname=>$plain_name,
630 modified=>'1',
631 siserver=>'localhost',
632 };
633 my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
634 if ($err != 0) {
635 &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
636 }
637 }
638 }
640 return;
641 }
644 ## @method TASKEND()
645 # @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.
646 # @param msg - STRING - xml message with tag 'macaddress'.
647 # @param msg_hash - HASHREF - message information parsed into a hash
648 # @param session_id - INTEGER - POE session id of the processing of this message
649 sub TASKEND {
650 my ($msg, $msg_hash, $session_id) = @_;
651 my $header = @{$msg_hash->{'header'}}[0];
652 my $target = @{$msg_hash->{'target'}}[0];
653 my $source = @{$msg_hash->{'source'}}[0];
654 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
656 # test whether content is an empty hash or a string which is required
657 my $content = @{$msg_hash->{$header}}[0];
658 if(ref($content) eq "HASH") { $content = ""; }
660 # clean up header
661 $header =~ s/CLMSG_//g;
663 if ($content eq "savelog 0") {
664 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
666 # set job to status 'done', job will be deleted automatically
667 my $sql_statement = "UPDATE $main::job_queue_tn ".
668 "SET status='done', modified='1'".
669 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
670 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
671 my $res = $main::job_db->update_dbentry( $sql_statement );
673 } else {
674 my $sql_statement = "UPDATE $main::job_queue_tn ".
675 "SET result='$header "."$content', modified='1' ".
676 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
677 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
678 my $res = $main::job_db->update_dbentry($sql_statement);
679 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
680 }
682 return;
683 }
686 ## @method TASKERROR()
687 # @details Message reports a FAI error. Job at job_queue_db is going to be updated.
688 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
689 # @param msg_hash - HASHREF - message information parsed into a hash
690 # @param session_id - INTEGER - POE session id of the processing of this message
691 sub TASKERROR {
692 my ($msg, $msg_hash, $session_id) = @_;
693 my $header = @{$msg_hash->{'header'}}[0];
694 my $source = @{$msg_hash->{'source'}}[0];
695 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
697 # clean up header
698 $header =~ s/CLMSG_//g;
700 # test whether content is an empty hash or a string which is required
701 my $content = @{$msg_hash->{$header}}[0];
702 if(ref($content) eq "HASH") { $content = ""; }
704 # set fai_state to localboot
705 &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
707 my $sql_statement = "UPDATE $main::job_queue_tn ".
708 "SET result='$header "."$content', modified='1' ".
709 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
710 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
711 my $res = $main::job_db->update_dbentry($sql_statement);
712 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
714 return;
715 }
718 ## @method HOOK()
719 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated.
720 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
721 # @param msg_hash - HASHREF - message information parsed into a hash
722 # @param session_id - INTEGER - POE session id of the processing of this message
723 sub HOOK {
724 my ($msg, $msg_hash, $session_id) = @_;
725 my $header = @{$msg_hash->{'header'}}[0];
726 my $source = @{$msg_hash->{'source'}}[0];
727 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
729 # clean up header
730 $header =~ s/CLMSG_//g;
732 # test whether content is an empty hash or a string which is required
733 my $content = @{$msg_hash->{$header}}[0];
734 if(not ref($content) eq "STRING") { $content = ""; }
736 my $sql_statement = "UPDATE $main::job_queue_tn ".
737 "SET result='$header "."$content', modified='1' ".
738 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
739 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
740 my $res = $main::job_db->update_dbentry($sql_statement);
741 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
743 return;
744 }
747 =pod
749 =head1 NAME
751 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
753 =head1 SYNOPSIS
755 use GOSA::GosaSupportDaemon;
756 use MIME::Base64;
758 =head1 DESCRIPTION
760 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients.
762 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
764 =head1 METHODS
766 =over 4
768 =item get_events ( )
770 =item confirm_usr_msg ( )
772 =item PROGRESS ( )
774 =item FAIREBOOT ( )
776 =item TASKSKIP ( )
778 =item TASKBEGIN ( )
780 =item TASKEND ( )
782 =item TASKERROR ( )
784 =item HOOK ( )
786 =item GOTOACTIVATION ( )
788 =item LOGIN ( )
790 =item LOGOUT ( )
792 =item CURRENTLY_LOGGED_IN ( )
794 =item save_fai_log ( )
796 =back
798 =head1 BUGS
800 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>
802 =head1 COPYRIGHT
804 This code is part of GOsa (L<http://www.gosa-project.org>)
806 Copyright (C) 2003-2008 GONICUS GmbH
808 This program is distributed in the hope that it will be useful,
809 but WITHOUT ANY WARRANTY; without even the implied warranty of
810 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
811 GNU General Public License for more details.
813 =cut
816 1;