Code

Removed smarty plugin loading
[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;
8 use strict;
9 use warnings;
11 use Data::Dumper;
12 use MIME::Base64;
13 use GOsaSI::GosaSupportDaemon;
15 use Exporter;
17 our @ISA = qw(Exporter);
19 my @events = (
20     "confirm_usr_msg",
21     "PROGRESS",
22     "FAIREBOOT",
23     "TASKSKIP",
24     "TASKBEGIN",
25     "TASKEND",
26     "TASKERROR",
27     "HOOK",
28     "GOTOACTIVATION",
29     "LOGIN",
30     "LOGOUT",
31     "CURRENTLY_LOGGED_IN",
32     "save_fai_log",
33     );
34 our @EXPORT = @events;
36 BEGIN {}
38 END {}
41 ## @method get_events()
42 # @details A brief function returning a list of functions which are exported by importing the module.
43 # @return List of all provided functions
44 sub get_events {
45     return \@events;
46 }
48 ## @method confirm_usr_msg()
49 # @details Confirmed messages are set in the messaging_db from d (deliverd) to s(seen). 
50 # @param msg - STRING - xml message with tags 'message', 'subject' and 'usr'
51 # @param msg_hash - HASHREF - message information parsed into a hash
52 # @param session_id - INTEGER - POE session id of the processing of this message
53 sub confirm_usr_msg {
54     my ($msg, $msg_hash, $session_id) = @_;
55     my $message = @{$msg_hash->{'message'}}[0];
56     my $subject = @{$msg_hash->{'subject'}}[0];
57     my $usr = @{$msg_hash->{'usr'}}[0];
59     # set update for this message
60     my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')"; 
61     &main::daemon_log("$session_id DEBUG: $sql", 7);
62     my $res = $main::messaging_db->exec_statement($sql); 
65     return;
66 }
69 ## @method save_fai_log()
70 # @details Creates under /var/log/fai/ the directory '$macaddress' and stores within all FAI log files from client.
71 # @param msg - STRING - xml message with tags 'macaddress' and 'save_fai_log'
72 # @param msg_hash - HASHREF - message information parsed into a hash
73 # @param session_id - INTEGER - POE session id of the processing of this message
74 sub save_fai_log {
75     my ($msg, $msg_hash, $session_id) = @_;
76     my $header = @{$msg_hash->{'header'}}[0];
77     my $source = @{$msg_hash->{'source'}}[0];
78     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
79     my $all_logs = @{$msg_hash->{$header}}[0];
81     # if there is nothing to log
82     if( ref($all_logs) eq "HASH" ) { 
83         &main::daemon_log("$session_id INFO: There is nothing to log!", 5);
84         return; 
85     }
86         
87     my $client_fai_log_dir = $main::client_fai_log_dir;
88     if (not -d $client_fai_log_dir) {
89         mkdir($client_fai_log_dir, 0755)
90     }
92     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
93     if (not -d $client_fai_log_dir) {
94         mkdir($client_fai_log_dir, 0755)
95     }
97     my $time = &get_time;
98     $time = substr($time, 0, 8)."_".substr($time, 8, 6);
99     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
100     mkdir($client_fai_log_dir, 0755);
102     my @all_logs = split(/log_file:/, $all_logs); 
103     foreach my $log (@all_logs) {
104         if (length $log == 0) { next; };
105         my ($log_file, $log_string) = split(":", $log);
106         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
108                 open(my $LOG_FILE, ">", "$client_fai_log_file"); 
109                 print $LOG_FILE &decode_base64($log_string);
110                 close($LOG_FILE);
111                 chown($main::root_uid, $main::adm_gid, $client_fai_log_file);
112                 chmod(0440, $client_fai_log_file);
114     }
115     return;
118 ## @method LOGIN()
119 # @details Reported user from client is added to login_users_db.
120 # @param msg - STRING - xml message with tag 'LOGIN'
121 # @param msg_hash - HASHREF - message information parsed into a hash
122 # @param session_id - INTEGER - POE session id of the processing of this message
123 sub LOGIN {
124     my ($msg, $msg_hash, $session_id) = @_;
125     my $header = @{$msg_hash->{'header'}}[0];
126     my $source = @{$msg_hash->{'source'}}[0];
127     my $login = @{$msg_hash->{$header}}[0];
128     my $res;
129     my $error_str;
131     # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
132         $res = &set_last_system($msg, $msg_hash, $session_id);
134     # Add user to login_users_db
135     my %add_hash = ( table=>$main::login_users_tn, 
136         primkey=> ['client', 'user'],
137         client=>$source,
138         user=>$login,
139         timestamp=>&get_time,
140         regserver=>'localhost',
141         ); 
142     ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
143     if ($res != 0)  {
144         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
145         return;
146     }
148     # Share login information with all other si-server
149     my %data = ( 'new_user'  => "$source;$login" );
150     my $info_msg = &build_msg("information_sharing", $main::server_address, "KNOWN_SERVER", \%data);
152     return ($info_msg);  
156 ## @method LOGOUT()
157 # @details Reported user from client is deleted from login_users_db.
158 # @param msg - STRING - xml message with tag 'LOGOUT'
159 # @param msg_hash - HASHREF - message information parsed into a hash
160 # @param session_id - INTEGER - POE session id of the processing of this message
161 sub LOGOUT {
162     my ($msg, $msg_hash, $session_id) = @_;
163     my $header = @{$msg_hash->{'header'}}[0];
164     my $source = @{$msg_hash->{'source'}}[0];
165     my $login = @{$msg_hash->{$header}}[0];
166     
167     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
168     my $res =  $main::login_users_db->del_dbentry($sql_statement);
169     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
170     
171     return;
175 ## @method CURRENTLY_LOGGED_IN()
176 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB. 
177 # @param msg - STRING - xml message
178 # @param msg_hash - HASHREF - message information parsed into a hash
179 # @param session_id - INTEGER - POE session id of the processing of this message
180 sub CURRENTLY_LOGGED_IN {
181     my ($msg, $msg_hash, $session_id) = @_;
182     my ($sql_statement, $db_res);
183     my $header = @{$msg_hash->{'header'}}[0];
184     my $source = @{$msg_hash->{'source'}}[0];
185     my $login = @{$msg_hash->{$header}}[0];
187     if(ref $login eq "HASH") { 
188         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
189         return;     
190     }
192     # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
193         my $res = &set_last_system($msg, $msg_hash, $session_id);
194     
195     # fetch all user currently assigned to the client at login_users_db
196     my %currently_logged_in_user = (); 
197     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
198     $db_res = $main::login_users_db->select_dbentry($sql_statement);
199     while( my($hit_id, $hit) = each(%{$db_res}) ) {
200         $currently_logged_in_user{$hit->{'user'}} = 1;
201     }
202     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
204     # update all reported users in login_user_db
205     my @logged_in_user = split(/\s+/, $login);
206     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
207     foreach my $user (@logged_in_user) {
208         my %add_hash = ( table=>$main::login_users_tn, 
209                 primkey=> ['client', 'user'],
210                 client=>$source,
211                 user=>$user,
212                 timestamp=>&get_time,
213                 regserver=>'localhost',
214                 ); 
215         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
216         if ($res != 0)  {
217             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
218             return;
219         }
221         delete $currently_logged_in_user{$user};
222     }
224     # if there is still a user in %currently_logged_in_user 
225     # although he is not reported by client 
226     # then delete it from $login_user_db
227     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
228         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
229                 "in at client '$source' but still found at login_user_db", 3); 
230         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
231         my $res =  $main::login_users_db->del_dbentry($sql_statement);
232         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
233     }
235     # Delete all users which logged in information is older than their logged_in_user_date_of_expiry
236     my $act_time = &get_time();
237     my $expiry_date = &calc_timestamp($act_time, "minus", $main::logged_in_user_date_of_expiry); 
239     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE CAST(timestamp as UNSIGNED)<$expiry_date"; 
240     $db_res = $main::login_users_db->select_dbentry($sql_statement);
242     while( my($hit_id, $hit) = each(%{$db_res}) ) {
243         &main::daemon_log("$session_id INFO: user '".$hit->{'user'}."' is no longer reported to be logged in at host '".$hit->{'client'}."'", 5);
244         my $sql = "DELETE FROM $main::login_users_tn WHERE (client='".$hit->{'client'}."' AND user='".$hit->{'user'}."')"; 
245         my $res =  $main::login_users_db->del_dbentry($sql);
246         &main::daemon_log("$session_id INFO: delete user '".$hit->{'user'}."' at client '".$hit->{'client'}."' from login_user_db", 5); 
247     }
249     # Inform all other server which users are logged in at clients registered at local server
250     my $info_sql = "SELECT * FROM $main::login_users_tn WHERE regserver='localhost'";
251     my $info_res = $main::login_users_db->select_dbentry($info_sql);
252     my $info_msg_hash = &create_xml_hash("information_sharing", $main::server_address, "KNOWN_SERVER");
253     while (my ($hit_id, $hit) = each(%$info_res)) {
254         &add_content2xml_hash($info_msg_hash, 'user_db', $hit->{'client'}.";".$hit->{'user'});
255     }
256     my $info_msg = &create_xml_string($info_msg_hash);
258     return ($info_msg);  
262 ## @method set_last_system()
263 # @details Message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
264 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
265 # @param msg_hash - HASHREF - message information parsed into a hash
266 # @param session_id - INTEGER - POE session id of the processing of this message
267 sub set_last_system {
268         my ($msg, $msg_hash, $session_id) = @_;
269         my $header = @{$msg_hash->{'header'}}[0];
270         my $source = @{$msg_hash->{'source'}}[0];
271     my $login = @{$msg_hash->{$header}}[0];
272     
273         # Sanity check of needed parameter
274         if (not exists $msg_hash->{'timestamp'}){
275                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
276                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
277                 &main::daemon_log($msg, 1);
278                 return;
279         }
280         if (@{$msg_hash->{'timestamp'}} != 1)  {
281                 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
282                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
283                 &ymain::daemon_log($msg, 1);
284                 return;
285         }
286         if (not exists $msg_hash->{'macaddress'}){
287                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
288                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
289                 &main::daemon_log($msg, 1);
290                 return;
291         }
292         if (@{$msg_hash->{'macaddress'}} != 1)  {
293                 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
294                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
295                 &ymain::daemon_log($msg, 1);
296                 return;
297         }
299         # Fetch needed parameter
300         my $mac =  @{$msg_hash->{'macaddress'}}[0];
301         my $timestamp = @{$msg_hash->{'timestamp'}}[0];
302         
303         # Prepare login list
304         my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
305     @login_list = &main::del_doubles(@login_list);
307         # Sanity check of login list
308         if (@login_list == 0) {
309                 # TODO
310                 return;
311         }
313         # Get system info
314         my $ldap_handle=&main::get_ldap_handle($session_id);
315         my $ldap_mesg= $ldap_handle->search(
316                                         base => $main::ldap_base,
317                                         scope => 'sub',
318                                         filter => "macAddress=$mac",
319                                         );
320         if ($ldap_mesg->count == 0) {
321                 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
322                                                 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
323                 &main::release_ldap_handle($ldap_handle);
324                 return;
325         }
327         my $ldap_entry = $ldap_mesg->pop_entry();
328         my $system_dn = $ldap_entry->dn();
329         
330         # For each logged in user set gotoLastSystem and gotoLastSystemLogin
331         foreach my $user (@login_list) {
332                 # Search user
333                 my $ldap_mesg= $ldap_handle->search(
334                                                 base => $main::ldap_base,
335                                                 scope => 'sub',
336                                                 filter => "(&(objectClass=gosaAccount)(uid=$user))",
337                                                 );
338                 # Sanity check of user search
339                 if ($ldap_mesg->count == 0) {
340                         &main::daemon_log("$session_id WARNING: no user with uid='$user' was found in base '".
341                                                         $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
343                 # Set gotoLastSystem and gotoLastSystemLogin
344                 } else {
345                         my $ldap_entry= $ldap_mesg->pop_entry();
346             my $do_update = 0;
348             # Set gotoLastSystem information
349             my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
350             if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
351                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' information for ldap entry 'uid=$user', do nothing!", 5);
352             } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
353                 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
354                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
355                 $do_update++;
356             } else {
357                 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
358                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
359                 $do_update++;
360             }
362             # Set gotoLastSystemLogin information
363             # Attention: only write information if last_system_dn and system_dn differs
364             my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
365             if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
366                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' information for ldap entry 'uid=$user', do nothing!", 5);
367             } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
368                 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
369                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
370                 $do_update++;
371             } else {
372                 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
373                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
374                 $do_update++;
375             }
377             if ($do_update) {
378                 my $result = $ldap_entry->update($ldap_handle);
379                 if ($result->code() != 0) {
380                     &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
381                             $result->{'errorMessage'}."\n".
382                             "\tbase: $main::ldap_base\n".
383                             "\tscope: 'sub'\n".
384                             "\tfilter: 'uid=$user'\n".
385                             "\tmessage: $msg", 1); 
386                 }
387             }
388                 }
389         }
390         &main::release_ldap_handle($ldap_handle);
392         return;
396 ## @method GOTOACTIVATION()
397 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
398 # @param msg - STRING - xml message with tag 'macaddress'
399 # @param msg_hash - HASHREF - message information parsed into a hash
400 # @param session_id - INTEGER - POE session id of the processing of this message
401 sub GOTOACTIVATION {
402     my ($msg, $msg_hash, $session_id) = @_;
403     my $header = @{$msg_hash->{'header'}}[0];
404     my $source = @{$msg_hash->{'source'}}[0];
405     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
407     # test whether content is an empty hash or a string which is required
408     my $content = @{$msg_hash->{$header}}[0];
409     if(ref($content) eq "HASH") { $content = ""; }
411     # clean up header
412     $header =~ s/CLMSG_//g;
414     my $sql_statement = "UPDATE $main::job_queue_tn ".
415             "SET progress='goto-activation', modified='1' ".
416             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
417     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
418     my $res = $main::job_db->update_dbentry($sql_statement);
419     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
420     return; 
424 ## @method PROGRESS()
425 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
426 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
427 # @param msg_hash - HASHREF - message information parsed into a hash
428 # @param session_id - INTEGER - POE session id of the processing of this message
429 sub PROGRESS {
430     my ($msg, $msg_hash, $session_id) = @_;
431     my $header = @{$msg_hash->{'header'}}[0];
432     my $source = @{$msg_hash->{'source'}}[0];
433     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
435     # test whether content is an empty hash or a string which is required
436     my $content = @{$msg_hash->{$header}}[0];
437     if(ref($content) eq "HASH") { $content = ""; }
439     # clean up header
440     $header =~ s/CLMSG_//g;
442     my $sql_statement = "UPDATE $main::job_queue_tn ".
443         "SET progress='$content', modified='1' ".
444         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
445     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
446     my $res = $main::job_db->update_dbentry($sql_statement);
447     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
449     return;
453 ## @method FAIREBOOT()
454 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
455 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
456 # @param msg_hash - HASHREF - message information parsed into a hash
457 # @param session_id - INTEGER - POE session id of the processing of this message
458 sub FAIREBOOT {
459     my ($msg, $msg_hash, $session_id) = @_;
460     my $header = @{$msg_hash->{'header'}}[0];
461     my $source = @{$msg_hash->{'source'}}[0];
462     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
464     # test whether content is an empty hash or a string which is required
465         my $content = @{$msg_hash->{$header}}[0];
466     if(ref($content) eq "HASH") { $content = ""; }
468     # clean up header
469     $header =~ s/CLMSG_//g;
471     my $sql_statement = "UPDATE $main::job_queue_tn ".
472             "SET result='$header "."$content', modified='1' ".
473             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
474     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
475     my $res = $main::job_db->update_dbentry($sql_statement);
476     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
478     return; 
482 ## @method TASKSKIP()
483 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
484 # @param msg - STRING - xml message with tag 'macaddress'.
485 # @param msg_hash - HASHREF - message information parsed into a hash
486 # @param session_id - INTEGER - POE session id of the processing of this message
487 sub TASKSKIP {
488     my ($msg, $msg_hash, $session_id) = @_;
489     my $header = @{$msg_hash->{'header'}}[0];
490     my $source = @{$msg_hash->{'source'}}[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     my $sql_statement = "UPDATE $main::job_queue_tn ".
501             "SET result='$header "."$content', modified='1' ".
502             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
503     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
504     my $res = $main::job_db->update_dbentry($sql_statement);
505     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
507     return; 
511 ## @method TASKBEGIN()
512 # @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. 
513 # @param msg - STRING - xml message with tag 'macaddress'.
514 # @param msg_hash - HASHREF - message information parsed into a hash
515 # @param session_id - INTEGER - POE session id of the processing of this message
516 sub TASKBEGIN {
517     my ($msg, $msg_hash, $session_id) = @_;
518     my $header = @{$msg_hash->{'header'}}[0];
519     my $source = @{$msg_hash->{'source'}}[0];
520     my $target = @{$msg_hash->{'target'}}[0];
521     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
523     # test whether content is an empty hash or a string which is required
524         my $content = @{$msg_hash->{$header}}[0];
525     if(ref($content) eq "HASH") { $content = ""; }
527     # clean up header
528     $header =~ s/CLMSG_//g;
530     # TASKBEGIN eq finish or faiend 
531     if (($content eq 'finish') 
532                         || ($content eq 'faiend')
533                         || ($content eq 'savelog')
534                         ) {
535         my $sql_statement = "UPDATE $main::job_queue_tn ".
536             "SET status='done', result='$header "."$content', modified='1' ".
537             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
538         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
539         my $res = $main::job_db->update_dbentry($sql_statement);
540         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
541         
542         # set fai_state to localboot
543         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
545         # TASKBEGIN eq chboot
546         } elsif (($content eq 'chboot')
547                 || ($content eq 'test')
548                 || ($content eq 'confdir')
549                 ) {
550                 # just ignor this client message
551                 # do nothing
553         # other TASKBEGIN msgs
554     } else {
555                 # TASKBEGIN msgs do only occour during a softupdate or a reinstallation
556                 # of a host. Set all waiting update- or reinstall-jobs for host to
557                 # processing so they can be handled correctly by the rest of the function.
558                 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')"; 
559                 &main::daemon_log("$session_id DEBUB: $waiting_sql", 7);
560                 my $waiting_res = $main::job_db->update_dbentry($waiting_sql);
562                 # Select processing jobs for host
563                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
564                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
565                 my $res = $main::job_db->select_dbentry($sql_statement);
567                 # there is exactly one job entry in queue for this host
568                 if (keys(%$res) == 1) {
569                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
570                         my $sql_statement = "UPDATE $main::job_queue_tn SET result='$header $content', modified='1', siserver='localhost' WHERE status='processing' AND macaddress LIKE '$macaddress'";
571                         my $err = $main::job_db->update_dbentry($sql_statement);
572                         if (not defined  $err) {
573                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
574                         }
575                         
576                 # There is no entry in queue or more than one entries in queue for this host
577                 } else {
578                         # In case of more than one running jobs in queue, delete all jobs
579                         if (keys(%$res) > 1) {
580                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
581                                                                 "delete entries", 7); 
583                 # set job to status 'done', job will be deleted automatically
584                 my $sql_statement = "UPDATE $main::job_queue_tn ".
585                     "SET status='done', modified='1'".
586                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
587                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
588                 my $res = $main::job_db->update_dbentry( $sql_statement );
590                         }
591                 
592                         # In case of no and more than one running jobs in queue, add one single job
594                         # Resolve plain name for host $macaddress
595                         my $plain_name;
596                         my $ldap_handle=&main::get_ldap_handle($session_id);
597                         my $mesg = $ldap_handle->search(
598                                         base => $main::ldap_base,
599                                         scope => 'sub',
600                                         attrs => ['cn'],
601                                         filter => "(macAddress=$macaddress)");
602                         if(not $mesg->code) {
603                                 my $entry= $mesg->entry(0);
604                                 $plain_name = $entry->get_value("cn");
605                         } else {
606                                 &main::daemon_log($mesg->error, 1);
607                                 $plain_name = "none";
608                         }
609                         &main::release_ldap_handle($ldap_handle);
611             # In any case add a new job to job queue
612                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
613                         my $func_dic = {table=>$main::job_queue_tn,
614                                         primkey=>['macaddress', 'headertag'],
615                                         timestamp=>&get_time,
616                                         status=>'processing',
617                                         result=>"$header $content",
618                                         progress=>'none',
619                                         headertag=>'trigger_action_reinstall',
620                                         targettag=>$target,
621                                         xmlmessage=>'none',
622                                         macaddress=>$macaddress,
623                                         plainname=>$plain_name,
624                     modified=>'1',
625                     siserver=>'localhost',
626                         };
627                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
628                         if ($err != 0)  {
629                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
630                         }
631                 }
632     }
634     return; 
638 ## @method TASKEND()
639 # @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. 
640 # @param msg - STRING - xml message with tag 'macaddress'.
641 # @param msg_hash - HASHREF - message information parsed into a hash
642 # @param session_id - INTEGER - POE session id of the processing of this message
643 sub TASKEND {
644     my ($msg, $msg_hash, $session_id) = @_;
645     my $header = @{$msg_hash->{'header'}}[0];
646     my $target = @{$msg_hash->{'target'}}[0];
647     my $source = @{$msg_hash->{'source'}}[0];
648     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
650     # test whether content is an empty hash or a string which is required
651     my $content = @{$msg_hash->{$header}}[0];
652     if(ref($content) eq "HASH") { $content = ""; }
654     # clean up header
655     $header =~ s/CLMSG_//g;
657         if ($content eq "savelog 0") {
658                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
659         
660         # set job to status 'done', job will be deleted automatically
661         my $sql_statement = "UPDATE $main::job_queue_tn ".
662                                         "SET status='done', modified='1'".
663                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
664         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
665         my $res = $main::job_db->update_dbentry( $sql_statement );
667         } else {
668         my $sql_statement = "UPDATE $main::job_queue_tn ".
669             "SET result='$header "."$content', modified='1' ".
670             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
671         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
672         my $res = $main::job_db->update_dbentry($sql_statement);
673         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
674         }
676     return; 
680 ## @method TASKERROR()
681 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
682 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
683 # @param msg_hash - HASHREF - message information parsed into a hash
684 # @param session_id - INTEGER - POE session id of the processing of this message
685 sub TASKERROR {
686     my ($msg, $msg_hash, $session_id) = @_;
687     my $header = @{$msg_hash->{'header'}}[0];
688     my $source = @{$msg_hash->{'source'}}[0];
689     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
691     # clean up header
692     $header =~ s/CLMSG_//g;
694     # test whether content is an empty hash or a string which is required
695     my $content = @{$msg_hash->{$header}}[0];
696     if(ref($content) eq "HASH") { $content = ""; } 
698         # set fai_state to localboot
699         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
700                 
701     my $sql_statement = "UPDATE $main::job_queue_tn ".
702             "SET result='$header "."$content', modified='1' ".
703             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
704     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
705     my $res = $main::job_db->update_dbentry($sql_statement);
706     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
708     return; 
712 ## @method HOOK()
713 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
714 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
715 # @param msg_hash - HASHREF - message information parsed into a hash
716 # @param session_id - INTEGER - POE session id of the processing of this message
717 sub HOOK {
718     my ($msg, $msg_hash, $session_id) = @_;
719     my $header = @{$msg_hash->{'header'}}[0];
720     my $source = @{$msg_hash->{'source'}}[0];
721     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
723     # clean up header
724     $header =~ s/CLMSG_//g;
726     # test whether content is an empty hash or a string which is required
727         my $content = @{$msg_hash->{$header}}[0];
728     if(not ref($content) eq "STRING") { $content = ""; }
730     my $sql_statement = "UPDATE $main::job_queue_tn ".
731             "SET result='$header "."$content', modified='1' ".
732             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
733     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
734     my $res = $main::job_db->update_dbentry($sql_statement);
735     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
737     return;
741 =pod
743 =head1 NAME
745 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
747 =head1 SYNOPSIS
749  use GOSA::GosaSupportDaemon;
750  use MIME::Base64;
752 =head1 DESCRIPTION
754 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
756 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
758 =head1 METHODS
760 =over 4
762 =item get_events ( )
764 =item confirm_usr_msg ( )
766 =item PROGRESS ( )
768 =item FAIREBOOT ( )
770 =item TASKSKIP ( )
772 =item TASKBEGIN ( )
774 =item TASKEND ( )
776 =item TASKERROR ( )
778 =item HOOK ( )
780 =item GOTOACTIVATION ( )
782 =item LOGIN ( )
784 =item LOGOUT ( )
786 =item CURRENTLY_LOGGED_IN ( )
788 =item save_fai_log ( )
790 =back
792 =head1 BUGS
794 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>
796 =head1 COPYRIGHT
798 This code is part of GOsa (L<http://www.gosa-project.org>)
800 Copyright (C) 2003-2008 GONICUS GmbH
802 This program is distributed in the hope that it will be useful,
803 but WITHOUT ANY WARRANTY; without even the implied warranty of
804 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
805 GNU General Public License for more details.
807 =cut
810 1;