Code

- Corrected various perl errors due to buf fixes and merging of patches
[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 Exporter;
12 use Data::Dumper;
13 use GOSA::GosaSupportDaemon;
14 use MIME::Base64;
16 our @ISA = qw(Exporter);
18 my @events = (
19     "confirm_usr_msg",
20     "PROGRESS",
21     "FAIREBOOT",
22     "TASKSKIP",
23     "TASKBEGIN",
24     "TASKEND",
25     "TASKERROR",
26     "HOOK",
27     "GOTOACTIVATION",
28     "LOGIN",
29     "LOGOUT",
30     "CURRENTLY_LOGGED_IN",
31     "save_fai_log",
32     );
33 our @EXPORT = @events;
35 BEGIN {}
37 END {}
40 ## @method get_events()
41 # @details A brief function returning a list of functions which are exported by importing the module.
42 # @return List of all provided functions
43 sub get_events {
44     return \@events;
45 }
47 ## @method confirm_usr_msg()
48 # @details Confirmed messages are set in the messaging_db from d (deliverd) to s(seen). 
49 # @param msg - STRING - xml message with tags 'message', 'subject' and 'usr'
50 # @param msg_hash - HASHREF - message information parsed into a hash
51 # @param session_id - INTEGER - POE session id of the processing of this message
52 sub confirm_usr_msg {
53     my ($msg, $msg_hash, $session_id) = @_;
54     my $message = @{$msg_hash->{'message'}}[0];
55     my $subject = @{$msg_hash->{'subject'}}[0];
56     my $usr = @{$msg_hash->{'usr'}}[0];
58     # set update for this message
59     my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')"; 
60     &main::daemon_log("$session_id DEBUG: $sql", 7);
61     my $res = $main::messaging_db->exec_statement($sql); 
64     return;
65 }
68 ## @method save_fai_log()
69 # @details Creates under /var/log/fai/ the directory '$macaddress' and stores within all FAI log files from client.
70 # @param msg - STRING - xml message with tags 'macaddress' and 'save_fai_log'
71 # @param msg_hash - HASHREF - message information parsed into a hash
72 # @param session_id - INTEGER - POE session id of the processing of this message
73 sub save_fai_log {
74     my ($msg, $msg_hash, $session_id) = @_;
75     my $header = @{$msg_hash->{'header'}}[0];
76     my $source = @{$msg_hash->{'source'}}[0];
77     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
78     my $all_logs = @{$msg_hash->{$header}}[0];
80     # if there is nothing to log
81     if( ref($all_logs) eq "HASH" ) { 
82         &main::daemon_log("$session_id INFO: There is nothing to log!", 5);
83         return; 
84     }
85         
86     my $client_fai_log_dir = $main::client_fai_log_dir;
87     if (not -d $client_fai_log_dir) {
88         mkdir($client_fai_log_dir, 0755)
89     }
91     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
92     if (not -d $client_fai_log_dir) {
93         mkdir($client_fai_log_dir, 0755)
94     }
96     my $time = &get_time;
97     $time = substr($time, 0, 8)."_".substr($time, 8, 6);
98     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
99     mkdir($client_fai_log_dir, 0755);
101     my @all_logs = split(/log_file:/, $all_logs); 
102     foreach my $log (@all_logs) {
103         if (length $log == 0) { next; };
104         my ($log_file, $log_string) = split(":", $log);
105         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
107                 open(my $LOG_FILE, ">", "$client_fai_log_file"); 
108                 print $LOG_FILE &decode_base64($log_string);
109                 close($LOG_FILE);
110                 chown($main::root_uid, $main::adm_gid, $client_fai_log_file);
111                 chmod(0440, $client_fai_log_file);
113     }
114     return;
117 ## @method LOGIN()
118 # @details Reported user from client is added to login_users_db.
119 # @param msg - STRING - xml message with tag 'LOGIN'
120 # @param msg_hash - HASHREF - message information parsed into a hash
121 # @param session_id - INTEGER - POE session id of the processing of this message
122 sub LOGIN {
123     my ($msg, $msg_hash, $session_id) = @_;
124     my $header = @{$msg_hash->{'header'}}[0];
125     my $source = @{$msg_hash->{'source'}}[0];
126     my $login = @{$msg_hash->{$header}}[0];
127     my $res;
128     my $error_str;
130     # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
131         $res = &set_last_system($msg, $msg_hash, $session_id);
133     # Add user to login_users_db
134     my %add_hash = ( table=>$main::login_users_tn, 
135         primkey=> ['client', 'user'],
136         client=>$source,
137         user=>$login,
138         timestamp=>&get_time,
139         regserver=>'localhost',
140         ); 
141     ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
142     if ($res != 0)  {
143         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
144         return;
145     }
147     # Share login information with all other si-server
148     my %data = ( 'new_user'  => "$source;$login" );
149     my $info_msg = &build_msg("information_sharing", $main::server_address, "KNOWN_SERVER", \%data);
151     return ($info_msg);  
155 ## @method LOGOUT()
156 # @details Reported user from client is deleted from login_users_db.
157 # @param msg - STRING - xml message with tag 'LOGOUT'
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 LOGOUT {
161     my ($msg, $msg_hash, $session_id) = @_;
162     my $header = @{$msg_hash->{'header'}}[0];
163     my $source = @{$msg_hash->{'source'}}[0];
164     my $login = @{$msg_hash->{$header}}[0];
165     
166     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
167     my $res =  $main::login_users_db->del_dbentry($sql_statement);
168     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
169     
170     return;
174 ## @method CURRENTLY_LOGGED_IN()
175 # @details Reported users from client are updated in login_users_db. Users which are no longer logged in are deleted from DB. 
176 # @param msg - STRING - xml message
177 # @param msg_hash - HASHREF - message information parsed into a hash
178 # @param session_id - INTEGER - POE session id of the processing of this message
179 sub CURRENTLY_LOGGED_IN {
180     my ($msg, $msg_hash, $session_id) = @_;
181     my ($sql_statement, $db_res);
182     my $header = @{$msg_hash->{'header'}}[0];
183     my $source = @{$msg_hash->{'source'}}[0];
184     my $login = @{$msg_hash->{$header}}[0];
186     if(ref $login eq "HASH") { 
187         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
188         return;     
189     }
191     # Invoke set_last_system; message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
192         my $res = &set_last_system($msg, $msg_hash, $session_id);
193     
194     # fetch all user currently assigned to the client at login_users_db
195     my %currently_logged_in_user = (); 
196     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
197     $db_res = $main::login_users_db->select_dbentry($sql_statement);
198     while( my($hit_id, $hit) = each(%{$db_res}) ) {
199         $currently_logged_in_user{$hit->{'user'}} = 1;
200     }
201     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
203     # update all reported users in login_user_db
204     my @logged_in_user = split(/\s+/, $login);
205     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
206     foreach my $user (@logged_in_user) {
207         my %add_hash = ( table=>$main::login_users_tn, 
208                 primkey=> ['client', 'user'],
209                 client=>$source,
210                 user=>$user,
211                 timestamp=>&get_time,
212                 regserver=>'localhost',
213                 ); 
214         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
215         if ($res != 0)  {
216             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
217             return;
218         }
220         delete $currently_logged_in_user{$user};
221     }
223     # if there is still a user in %currently_logged_in_user 
224     # although he is not reported by client 
225     # then delete it from $login_user_db
226     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
227         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
228                 "in at client '$source' but still found at login_user_db", 3); 
229         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
230         my $res =  $main::login_users_db->del_dbentry($sql_statement);
231         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
232     }
234     # Delete all users which logged in information is older than their logged_in_user_date_of_expiry
235     my $act_time = &get_time();
236     my $expiry_date = &calc_timestamp($act_time, "minus", $main::logged_in_user_date_of_expiry); 
238     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE CAST(timestamp as UNSIGNED)<$expiry_date"; 
239     $db_res = $main::login_users_db->select_dbentry($sql_statement);
241     while( my($hit_id, $hit) = each(%{$db_res}) ) {
242         &main::daemon_log("$session_id INFO: user '".$hit->{'user'}."' is no longer reported to be logged in at host '".$hit->{'client'}."'", 5);
243         my $sql = "DELETE FROM $main::login_users_tn WHERE (client='".$hit->{'client'}."' AND user='".$hit->{'user'}."')"; 
244         my $res =  $main::login_users_db->del_dbentry($sql);
245         &main::daemon_log("$session_id INFO: delete user '".$hit->{'user'}."' at client '".$hit->{'client'}."' from login_user_db", 5); 
246     }
248     # Inform all other server which users are logged in at clients registered at local server
249     my $info_sql = "SELECT * FROM $main::login_users_tn WHERE regserver='localhost'";
250     my $info_res = $main::login_users_db->select_dbentry($info_sql);
251     my $info_msg_hash = &create_xml_hash("information_sharing", $main::server_address, "KNOWN_SERVER");
252     while (my ($hit_id, $hit) = each(%$info_res)) {
253         &add_content2xml_hash($info_msg_hash, 'user_db', $hit->{'client'}.";".$hit->{'user'});
254     }
255     my $info_msg = &create_xml_string($info_msg_hash);
257     return ($info_msg);  
261 ## @method set_last_system()
262 # @details Message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
263 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
264 # @param msg_hash - HASHREF - message information parsed into a hash
265 # @param session_id - INTEGER - POE session id of the processing of this message
266 sub set_last_system {
267         my ($msg, $msg_hash, $session_id) = @_;
268         my $header = @{$msg_hash->{'header'}}[0];
269         my $source = @{$msg_hash->{'source'}}[0];
270     my $login = @{$msg_hash->{$header}}[0];
271     
272         # Sanity check of needed parameter
273         if (not exists $msg_hash->{'timestamp'}){
274                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
275                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
276                 &main::daemon_log($msg, 1);
277                 return;
278         }
279         if (@{$msg_hash->{'timestamp'}} != 1)  {
280                 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
281                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
282                 &ymain::daemon_log($msg, 1);
283                 return;
284         }
285         if (not exists $msg_hash->{'macaddress'}){
286                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
287                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
288                 &main::daemon_log($msg, 1);
289                 return;
290         }
291         if (@{$msg_hash->{'macaddress'}} != 1)  {
292                 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
293                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
294                 &ymain::daemon_log($msg, 1);
295                 return;
296         }
298         # Fetch needed parameter
299         my $mac =  @{$msg_hash->{'macaddress'}}[0];
300         my $timestamp = @{$msg_hash->{'timestamp'}}[0];
301         
302         # Prepare login list
303         my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
304     @login_list = &main::del_doubles(@login_list);
306         # Sanity check of login list
307         if (@login_list == 0) {
308                 # TODO
309                 return;
310         }
312         # Get system info
313         my $ldap_handle=&main::get_ldap_handle($session_id);
314         my $ldap_mesg= $ldap_handle->search(
315                                         base => $main::ldap_base,
316                                         scope => 'sub',
317                                         filter => "macAddress=$mac",
318                                         );
319         if ($ldap_mesg->count == 0) {
320                 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
321                                                 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
322                 &main::release_ldap_handle($ldap_handle);
323                 return;
324         }
326         my $ldap_entry = $ldap_mesg->pop_entry();
327         my $system_dn = $ldap_entry->dn();
328         
329         # For each logged in user set gotoLastSystem and gotoLastSystemLogin
330         foreach my $user (@login_list) {
331                 # Search user
332                 my $ldap_mesg= $ldap_handle->search(
333                                                 base => $main::ldap_base,
334                                                 scope => 'sub',
335                                                 filter => "(&(objectClass=gosaAccount)(uid=$user))",
336                                                 );
337                 # Sanity check of user search
338                 if ($ldap_mesg->count == 0) {
339                         &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
340                                                         $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
342                 # Set gotoLastSystem and gotoLastSystemLogin
343                 } else {
344                         my $ldap_entry= $ldap_mesg->pop_entry();
345             my $do_update = 0;
347             # Set gotoLastSystem information
348             my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
349             if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
350                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' information for ldap entry 'uid=$user', do nothing!", 5);
351             } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
352                 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
353                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
354                 $do_update++;
355             } else {
356                 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
357                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
358                 $do_update++;
359             }
361             # Set gotoLastSystemLogin information
362             # Attention: only write information if last_system_dn and system_dn differs
363             my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
364             if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
365                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' information for ldap entry 'uid=$user', do nothing!", 5);
366             } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
367                 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
368                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
369                 $do_update++;
370             } else {
371                 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
372                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
373                 $do_update++;
374             }
376             if ($do_update) {
377                 my $result = $ldap_entry->update($ldap_handle);
378                 if ($result->code() != 0) {
379                     &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
380                             $result->{'errorMessage'}."\n".
381                             "\tbase: $main::ldap_base\n".
382                             "\tscope: 'sub'\n".
383                             "\tfilter: 'uid=$user'\n".
384                             "\tmessage: $msg", 1); 
385                 }
386             }
387                 }
388         }
389         &main::release_ldap_handle($ldap_handle);
391         return;
395 ## @method GOTOACTIVATION()
396 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
397 # @param msg - STRING - xml message with tag 'macaddress'
398 # @param msg_hash - HASHREF - message information parsed into a hash
399 # @param session_id - INTEGER - POE session id of the processing of this message
400 sub GOTOACTIVATION {
401     my ($msg, $msg_hash, $session_id) = @_;
402     my $header = @{$msg_hash->{'header'}}[0];
403     my $source = @{$msg_hash->{'source'}}[0];
404     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
406     # test whether content is an empty hash or a string which is required
407     my $content = @{$msg_hash->{$header}}[0];
408     if(ref($content) eq "HASH") { $content = ""; }
410     # clean up header
411     $header =~ s/CLMSG_//g;
413     my $sql_statement = "UPDATE $main::job_queue_tn ".
414             "SET progress='goto-activation', modified='1' ".
415             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
416     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
417     my $res = $main::job_db->update_dbentry($sql_statement);
418     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
419     return; 
423 ## @method PROGRESS()
424 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
425 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
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 PROGRESS {
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 progress='$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 FAIREBOOT()
453 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
454 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
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 FAIREBOOT {
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 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 TASKSKIP()
482 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
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 TASKSKIP {
487     my ($msg, $msg_hash, $session_id) = @_;
488     my $header = @{$msg_hash->{'header'}}[0];
489     my $source = @{$msg_hash->{'source'}}[0];
490     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
492     # test whether content is an empty hash or a string which is required
493         my $content = @{$msg_hash->{$header}}[0];
494     if(ref($content) eq "HASH") { $content = ""; }
496     # clean up header
497     $header =~ s/CLMSG_//g;
499     my $sql_statement = "UPDATE $main::job_queue_tn ".
500             "SET result='$header "."$content', modified='1' ".
501             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
502     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
503     my $res = $main::job_db->update_dbentry($sql_statement);
504     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
506     return; 
510 ## @method TASKBEGIN()
511 # @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. 
512 # @param msg - STRING - xml message with tag 'macaddress'.
513 # @param msg_hash - HASHREF - message information parsed into a hash
514 # @param session_id - INTEGER - POE session id of the processing of this message
515 sub TASKBEGIN {
516     my ($msg, $msg_hash, $session_id) = @_;
517     my $header = @{$msg_hash->{'header'}}[0];
518     my $source = @{$msg_hash->{'source'}}[0];
519     my $target = @{$msg_hash->{'target'}}[0];
520     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
522     # test whether content is an empty hash or a string which is required
523         my $content = @{$msg_hash->{$header}}[0];
524     if(ref($content) eq "HASH") { $content = ""; }
526     # clean up header
527     $header =~ s/CLMSG_//g;
529     # TASKBEGIN eq finish or faiend 
530     if (($content eq 'finish') 
531                         || ($content eq 'faiend')
532                         || ($content eq 'savelog')
533                         ) {
534         my $sql_statement = "UPDATE $main::job_queue_tn ".
535             "SET status='done', result='$header "."$content', modified='1' ".
536             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
537         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
538         my $res = $main::job_db->update_dbentry($sql_statement);
539         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
540         
541         # set fai_state to localboot
542         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
544         # TASKBEGIN eq chboot
545         } elsif (($content eq 'chboot')
546                 || ($content eq 'test')
547                 || ($content eq 'confdir')
548                 ) {
549                 # just ignor this client message
550                 # do nothing
552         # other TASKBEGIN msgs
553     } else {
554                 # TASKBEGIN msgs do only occour during a softupdate or a reinstallation
555                 # of a host. Set all waiting update- or reinstall-jobs for host to
556                 # processing so they can be handled correctly by the rest of the function.
557                 my $waiting_sql = "UPDATE $main::job_queue_tn SET status='processing' WHERE status='waiting' AND macaddress LIKE '$macaddress' AND (headertag='trigger_action_update' OR headertag='trigger_action_reinstall')"; 
558                 &main::daemon_log("$session_id DEBUB: $waiting_sql", 7);
559                 my $waiting_res = $main::job_db->update_dbentry($waiting_sql);
561                 # Select processing jobs for host
562                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
563                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
564                 my $res = $main::job_db->select_dbentry($sql_statement);
566                 # there is exactly one job entry in queue for this host
567                 if (keys(%$res) == 1) {
568                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
569                         my $sql_statement = "UPDATE $main::job_queue_tn SET result='$header $content', modified='1', siserver='localhost' WHERE status='processing' AND macaddress LIKE '$macaddress'";
570                         my $err = $main::job_db->update_dbentry($sql_statement);
571                         if (not defined  $err) {
572                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
573                         }
574                         
575                 # There is no entry in queue or more than one entries in queue for this host
576                 } else {
577                         # In case of more than one running jobs in queue, delete all jobs
578                         if (keys(%$res) > 1) {
579                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
580                                                                 "delete entries", 7); 
582                 # set job to status 'done', job will be deleted automatically
583                 my $sql_statement = "UPDATE $main::job_queue_tn ".
584                     "SET status='done', modified='1'".
585                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
586                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
587                 my $res = $main::job_db->update_dbentry( $sql_statement );
589                         }
590                 
591                         # In case of no and more than one running jobs in queue, add one single job
593                         # Resolve plain name for host $macaddress
594                         my $plain_name;
595                         my $ldap_handle=&main::get_ldap_handle($session_id);
596                         my $mesg = $ldap_handle->search(
597                                         base => $main::ldap_base,
598                                         scope => 'sub',
599                                         attrs => ['cn'],
600                                         filter => "(macAddress=$macaddress)");
601                         if(not $mesg->code) {
602                                 my $entry= $mesg->entry(0);
603                                 $plain_name = $entry->get_value("cn");
604                         } else {
605                                 &main::daemon_log($mesg->error, 1);
606                                 $plain_name = "none";
607                         }
608                         &main::release_ldap_handle($ldap_handle);
610             # In any case add a new job to job queue
611                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
612                         my $func_dic = {table=>$main::job_queue_tn,
613                                         primkey=>['macaddress', 'headertag'],
614                                         timestamp=>&get_time,
615                                         status=>'processing',
616                                         result=>"$header $content",
617                                         progress=>'none',
618                                         headertag=>'trigger_action_reinstall',
619                                         targettag=>$target,
620                                         xmlmessage=>'none',
621                                         macaddress=>$macaddress,
622                                         plainname=>$plain_name,
623                     modified=>'1',
624                     siserver=>'localhost',
625                         };
626                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
627                         if ($err != 0)  {
628                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
629                         }
630                 }
631     }
633     return; 
637 ## @method TASKEND()
638 # @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. 
639 # @param msg - STRING - xml message with tag 'macaddress'.
640 # @param msg_hash - HASHREF - message information parsed into a hash
641 # @param session_id - INTEGER - POE session id of the processing of this message
642 sub TASKEND {
643     my ($msg, $msg_hash, $session_id) = @_;
644     my $header = @{$msg_hash->{'header'}}[0];
645     my $target = @{$msg_hash->{'target'}}[0];
646     my $source = @{$msg_hash->{'source'}}[0];
647     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
649     # test whether content is an empty hash or a string which is required
650     my $content = @{$msg_hash->{$header}}[0];
651     if(ref($content) eq "HASH") { $content = ""; }
653     # clean up header
654     $header =~ s/CLMSG_//g;
656         if ($content eq "savelog 0") {
657                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
658         
659         # set job to status 'done', job will be deleted automatically
660         my $sql_statement = "UPDATE $main::job_queue_tn ".
661                                         "SET status='done', modified='1'".
662                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
663         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
664         my $res = $main::job_db->update_dbentry( $sql_statement );
666         } else {
667         my $sql_statement = "UPDATE $main::job_queue_tn ".
668             "SET result='$header "."$content', modified='1' ".
669             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
670         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
671         my $res = $main::job_db->update_dbentry($sql_statement);
672         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
673         }
675     return; 
679 ## @method TASKERROR()
680 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
681 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
682 # @param msg_hash - HASHREF - message information parsed into a hash
683 # @param session_id - INTEGER - POE session id of the processing of this message
684 sub TASKERROR {
685     my ($msg, $msg_hash, $session_id) = @_;
686     my $header = @{$msg_hash->{'header'}}[0];
687     my $source = @{$msg_hash->{'source'}}[0];
688     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
690     # clean up header
691     $header =~ s/CLMSG_//g;
693     # test whether content is an empty hash or a string which is required
694     my $content = @{$msg_hash->{$header}}[0];
695     if(ref($content) eq "HASH") { $content = ""; } 
697         # set fai_state to localboot
698         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
699                 
700     my $sql_statement = "UPDATE $main::job_queue_tn ".
701             "SET 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 ## @method HOOK()
712 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
713 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
714 # @param msg_hash - HASHREF - message information parsed into a hash
715 # @param session_id - INTEGER - POE session id of the processing of this message
716 sub HOOK {
717     my ($msg, $msg_hash, $session_id) = @_;
718     my $header = @{$msg_hash->{'header'}}[0];
719     my $source = @{$msg_hash->{'source'}}[0];
720     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
722     # clean up header
723     $header =~ s/CLMSG_//g;
725     # test whether content is an empty hash or a string which is required
726         my $content = @{$msg_hash->{$header}}[0];
727     if(not ref($content) eq "STRING") { $content = ""; }
729     my $sql_statement = "UPDATE $main::job_queue_tn ".
730             "SET result='$header "."$content', modified='1' ".
731             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
732     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
733     my $res = $main::job_db->update_dbentry($sql_statement);
734     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
736     return;
740 =pod
742 =head1 NAME
744 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
746 =head1 SYNOPSIS
748  use GOSA::GosaSupportDaemon;
749  use MIME::Base64;
751 =head1 DESCRIPTION
753 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
755 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
757 =head1 METHODS
759 =over 4
761 =item get_events ( )
763 =item confirm_usr_msg ( )
765 =item PROGRESS ( )
767 =item FAIREBOOT ( )
769 =item TASKSKIP ( )
771 =item TASKBEGIN ( )
773 =item TASKEND ( )
775 =item TASKERROR ( )
777 =item HOOK ( )
779 =item GOTOACTIVATION ( )
781 =item LOGIN ( )
783 =item LOGOUT ( )
785 =item CURRENTLY_LOGGED_IN ( )
787 =item save_fai_log ( )
789 =back
791 =head1 BUGS
793 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>
795 =head1 COPYRIGHT
797 This code is part of GOsa (L<http://www.gosa-project.org>)
799 Copyright (C) 2003-2008 GONICUS GmbH
801 This program is distributed in the hope that it will be useful,
802 but WITHOUT ANY WARRANTY; without even the implied warranty of
803 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
804 GNU General Public License for more details.
806 =cut
809 1;