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