Code

bugfix: write gotoLastSystem and gotoLastSystemLogin to LDAP
[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                         if (defined($ldap_entry->get_value('gotoLastSystem'))) {
318                                         $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
319                     &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!");
320                         } else {
321                                         $ldap_entry->add( 'gotoLastSystem' => $system_dn );
322                     &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!");
323                         }
324                         if (defined($ldap_entry->get_value('gotoLastSystemLogin'))) {
325                                         $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
326                     &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!");
327                         } else {
328                                         $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
329                     &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!");
330                         }
331                         my $result = $ldap_entry->update($ldap_handle);
332                         if ($result->code() != 0) {
333                                         &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
334                                                                         $result->{'errorMessage'}."\n".
335                             "\tbase: $main::ldap_base\n".
336                             "\tscope: 'sub'\n".
337                             "\tfilter: 'uid=$user'\n".
338                             "\tmessage: $msg", 1); 
339                         }
340                 }
341         }
343         return;
347 ## @method GOTOACTIVATION()
348 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
349 # @param msg - STRING - xml message with tag 'macaddress'
350 # @param msg_hash - HASHREF - message information parsed into a hash
351 # @param session_id - INTEGER - POE session id of the processing of this message
352 sub GOTOACTIVATION {
353     my ($msg, $msg_hash, $session_id) = @_;
354     my $header = @{$msg_hash->{'header'}}[0];
355     my $source = @{$msg_hash->{'source'}}[0];
356     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
358     # test whether content is an empty hash or a string which is required
359     my $content = @{$msg_hash->{$header}}[0];
360     if(ref($content) eq "HASH") { $content = ""; }
362     # clean up header
363     $header =~ s/CLMSG_//g;
365     my $sql_statement = "UPDATE $main::job_queue_tn ".
366             "SET status='processing', progress='goto-activation', modified='1' ".
367             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
368     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
369     my $res = $main::job_db->update_dbentry($sql_statement);
370     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
371     return; 
375 ## @method PROGRESS()
376 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
377 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
378 # @param msg_hash - HASHREF - message information parsed into a hash
379 # @param session_id - INTEGER - POE session id of the processing of this message
380 sub PROGRESS {
381     my ($msg, $msg_hash, $session_id) = @_;
382     my $header = @{$msg_hash->{'header'}}[0];
383     my $source = @{$msg_hash->{'source'}}[0];
384     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
386     # test whether content is an empty hash or a string which is required
387     my $content = @{$msg_hash->{$header}}[0];
388     if(ref($content) eq "HASH") { $content = ""; }
390     # clean up header
391     $header =~ s/CLMSG_//g;
393     my $sql_statement = "UPDATE $main::job_queue_tn ".
394         "SET progress='$content', modified='1' ".
395         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
396     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
397     my $res = $main::job_db->update_dbentry($sql_statement);
398     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
400     return;
404 ## @method FAIREBOOT()
405 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
406 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
407 # @param msg_hash - HASHREF - message information parsed into a hash
408 # @param session_id - INTEGER - POE session id of the processing of this message
409 sub FAIREBOOT {
410     my ($msg, $msg_hash, $session_id) = @_;
411     my $header = @{$msg_hash->{'header'}}[0];
412     my $source = @{$msg_hash->{'source'}}[0];
413     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
415     # test whether content is an empty hash or a string which is required
416         my $content = @{$msg_hash->{$header}}[0];
417     if(ref($content) eq "HASH") { $content = ""; }
419     # clean up header
420     $header =~ s/CLMSG_//g;
422     my $sql_statement = "UPDATE $main::job_queue_tn ".
423             "SET status='processing', result='$header "."$content', modified='1' ".
424             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
425     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
426     my $res = $main::job_db->update_dbentry($sql_statement);
427     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
429     return; 
433 ## @method TASKSKIP()
434 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
435 # @param msg - STRING - xml message with tag 'macaddress'.
436 # @param msg_hash - HASHREF - message information parsed into a hash
437 # @param session_id - INTEGER - POE session id of the processing of this message
438 sub TASKSKIP {
439     my ($msg, $msg_hash, $session_id) = @_;
440     my $header = @{$msg_hash->{'header'}}[0];
441     my $source = @{$msg_hash->{'source'}}[0];
442     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
444     # test whether content is an empty hash or a string which is required
445         my $content = @{$msg_hash->{$header}}[0];
446     if(ref($content) eq "HASH") { $content = ""; }
448     # clean up header
449     $header =~ s/CLMSG_//g;
451     my $sql_statement = "UPDATE $main::job_queue_tn ".
452             "SET status='processing', result='$header "."$content', modified='1' ".
453             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
454     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
455     my $res = $main::job_db->update_dbentry($sql_statement);
456     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
458     return; 
462 ## @method TASKBEGIN()
463 # @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. 
464 # @param msg - STRING - xml message with tag 'macaddress'.
465 # @param msg_hash - HASHREF - message information parsed into a hash
466 # @param session_id - INTEGER - POE session id of the processing of this message
467 sub TASKBEGIN {
468     my ($msg, $msg_hash, $session_id) = @_;
469     my $header = @{$msg_hash->{'header'}}[0];
470     my $source = @{$msg_hash->{'source'}}[0];
471     my $target = @{$msg_hash->{'target'}}[0];
472     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
474     # test whether content is an empty hash or a string which is required
475         my $content = @{$msg_hash->{$header}}[0];
476     if(ref($content) eq "HASH") { $content = ""; }
478     # clean up header
479     $header =~ s/CLMSG_//g;
481     # TASKBEGIN eq finish or faiend 
482     if (($content eq 'finish') 
483                         || ($content eq 'faiend')
484                         || ($content eq 'savelog')
485                         ) {
486         my $sql_statement = "UPDATE $main::job_queue_tn ".
487             "SET status='done', result='$header "."$content', modified='1' ".
488             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
489         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
490         my $res = $main::job_db->update_dbentry($sql_statement);
491         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
492         
493         # set fai_state to localboot
494         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
496         # TASKBEGIN eq chboot
497         } elsif (($content eq 'chboot')
498                 || ($content eq 'test')
499                 || ($content eq 'confdir')
500                 ) {
501                 # just ignor this client message
502                 # do nothing
504         # other TASKBEGIN msgs
505     } else {
506                 # select processing jobs for host
507                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
508                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
509                 my $res = $main::job_db->select_dbentry($sql_statement);
511                 # there is exactly one job entry in queue for this host
512                 if (keys(%$res) == 1) {
513                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
514                         my $sql_statement = "UPDATE $main::job_queue_tn ".
515                 "SET result='$header $content', modified='1', siserver='localhost' ".
516                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
517                         my $err = $main::job_db->update_dbentry($sql_statement);
518                         if (not defined  $err) {
519                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
520                         }
521                         
522                 # there is no entry or more than one enties
523                 } else {
524                         # in case of more than one running jobs in queue, delete all jobs
525                         if (keys(%$res) > 1) {
526                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
527                                                                 "delete entries", 7); 
529                 # set job to status 'done', job will be deleted automatically
530                 my $sql_statement = "UPDATE $main::job_queue_tn ".
531                     "SET status='done', modified='1'".
532                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
533                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
534                 my $res = $main::job_db->update_dbentry( $sql_statement );
536                         }
537                 
538                         # in case of no and more than one running jobs in queue, add one single job
539                         # resolve plain name for host $macaddress
540                         my $plain_name;
541                         my $ldap_handle = &main::get_ldap_handle($session_id);
542                         if( not defined $ldap_handle ) {
543                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
544                                 $plain_name = "none";
546                         # try to fetch a 'real name'
547                         } else {
548                                 my $mesg = $ldap_handle->search(
549                                                 base => $main::ldap_base,
550                                                 scope => 'sub',
551                                                 attrs => ['cn'],
552                                                 filter => "(macAddress=$macaddress)");
553                                 if($mesg->code) {
554                                         &main::daemon_log($mesg->error, 1);
555                                         $plain_name = "none";
556                                 } else {
557                                         my $entry= $mesg->entry(0);
558                                         $plain_name = $entry->get_value("cn");
559                                 }
560                         }
562             # In any case add a new job to job queue
563                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
564                         my $func_dic = {table=>$main::job_queue_tn,
565                                         primkey=>['macaddress', 'headertag'],
566                                         timestamp=>&get_time,
567                                         status=>'processing',
568                                         result=>"$header $content",
569                                         progress=>'none',
570                                         headertag=>'trigger_action_reinstall',
571                                         targettag=>$target,
572                                         xmlmessage=>'none',
573                                         macaddress=>$macaddress,
574                                         plainname=>$plain_name,
575                     modified=>'1',
576                     siserver=>'localhost',
577                         };
578                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
579                         if ($err != 0)  {
580                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
581                         }
582                 }
583     }
585     return; 
589 ## @method TASKEND()
590 # @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. 
591 # @param msg - STRING - xml message with tag 'macaddress'.
592 # @param msg_hash - HASHREF - message information parsed into a hash
593 # @param session_id - INTEGER - POE session id of the processing of this message
594 sub TASKEND {
595     my ($msg, $msg_hash, $session_id) = @_;
596     my $header = @{$msg_hash->{'header'}}[0];
597     my $target = @{$msg_hash->{'target'}}[0];
598     my $source = @{$msg_hash->{'source'}}[0];
599     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
601     # test whether content is an empty hash or a string which is required
602     my $content = @{$msg_hash->{$header}}[0];
603     if(ref($content) eq "HASH") { $content = ""; }
605     # clean up header
606     $header =~ s/CLMSG_//g;
608         if ($content eq "savelog 0") {
609                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
610         
611         # set job to status 'done', job will be deleted automatically
612         my $sql_statement = "UPDATE $main::job_queue_tn ".
613                                         "SET status='done', modified='1'".
614                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
615         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
616         my $res = $main::job_db->update_dbentry( $sql_statement );
618         } else {
619         my $sql_statement = "UPDATE $main::job_queue_tn ".
620             "SET status='processing', result='$header "."$content', modified='1' ".
621             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
622         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
623         my $res = $main::job_db->update_dbentry($sql_statement);
624         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
625         }
627     return; 
631 ## @method TASKERROR()
632 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
633 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
634 # @param msg_hash - HASHREF - message information parsed into a hash
635 # @param session_id - INTEGER - POE session id of the processing of this message
636 sub TASKERROR {
637     my ($msg, $msg_hash, $session_id) = @_;
638     my $header = @{$msg_hash->{'header'}}[0];
639     my $source = @{$msg_hash->{'source'}}[0];
640     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
642     # clean up header
643     $header =~ s/CLMSG_//g;
645     # test whether content is an empty hash or a string which is required
646     my $content = @{$msg_hash->{$header}}[0];
647     if(ref($content) eq "HASH") { $content = ""; } 
649         # set fai_state to localboot
650         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
651                 
652     my $sql_statement = "UPDATE $main::job_queue_tn ".
653             "SET status='processing', result='$header "."$content', modified='1' ".
654             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
655     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
656     my $res = $main::job_db->update_dbentry($sql_statement);
657     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
659     return; 
663 ## @method HOOK()
664 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
665 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
666 # @param msg_hash - HASHREF - message information parsed into a hash
667 # @param session_id - INTEGER - POE session id of the processing of this message
668 sub HOOK {
669     my ($msg, $msg_hash, $session_id) = @_;
670     my $header = @{$msg_hash->{'header'}}[0];
671     my $source = @{$msg_hash->{'source'}}[0];
672     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
674     # clean up header
675     $header =~ s/CLMSG_//g;
677     # test whether content is an empty hash or a string which is required
678         my $content = @{$msg_hash->{$header}}[0];
679     if(not ref($content) eq "STRING") { $content = ""; }
681     my $sql_statement = "UPDATE $main::job_queue_tn ".
682             "SET status='processing', result='$header "."$content', modified='1' ".
683             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
684     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
685     my $res = $main::job_db->update_dbentry($sql_statement);
686     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
688     return;
692 =pod
694 =head1 NAME
696 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
698 =head1 SYNOPSIS
700  use GOSA::GosaSupportDaemon;
701  use MIME::Base64;
703 =head1 DESCRIPTION
705 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
707 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
709 =head1 METHODS
711 =over 4
713 =item get_events ( )
715 =item confirm_usr_msg ( )
717 =item PROGRESS ( )
719 =item FAIREBOOT ( )
721 =item TASKSKIP ( )
723 =item TASKBEGIN ( )
725 =item TASKEND ( )
727 =item TASKERROR ( )
729 =item HOOK ( )
731 =item GOTOACTIVATION ( )
733 =item LOGIN ( )
735 =item LOGOUT ( )
737 =item CURRENTLY_LOGGED_IN ( )
739 =item save_fai_log ( )
741 =back
743 =head1 BUGS
745 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>
747 =head1 COPYRIGHT
749 This code is part of GOsa (L<http://www.gosa-project.org>)
751 Copyright (C) 2003-2008 GONICUS GmbH
753 This program is distributed in the hope that it will be useful,
754 but WITHOUT ANY WARRANTY; without even the implied warranty of
755 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
756 GNU General Public License for more details.
758 =cut
761 1;