Code

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