Code

bugfix: get_host_with_module, create mas at the right position
[gosa.git] / gosa-si / server / events / clMessages.pm
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; }
79         
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;
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;   
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];
146     
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); 
150     
151     return;
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);
174     
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;
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];
242     
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];
272         
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();
300         
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;
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; 
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;
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; 
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; 
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); 
511         
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                         }
540                         
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                         }
556                 
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; 
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);
629         
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; 
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);
670                 
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; 
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;
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;