Code

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