Code

No longer pass on the list of users at local clients to all known
[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     return;
250 ## @method set_last_system()
251 # @details Message sets ldap attributes 'gotoLastSystemLogin' and 'gotoLastSystem'
252 # @param msg - STRING - xml message with tag 'last_system_login' and 'last_system'
253 # @param msg_hash - HASHREF - message information parsed into a hash
254 # @param session_id - INTEGER - POE session id of the processing of this message
255 sub set_last_system {
256         my ($msg, $msg_hash, $session_id) = @_;
257         my $header = @{$msg_hash->{'header'}}[0];
258         my $source = @{$msg_hash->{'source'}}[0];
259     my $login = @{$msg_hash->{$header}}[0];
260     
261         # Sanity check of needed parameter
262         if (not exists $msg_hash->{'timestamp'}){
263                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'timestamp', ".
264                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
265                 &main::daemon_log($msg, 1);
266                 return;
267         }
268         if (@{$msg_hash->{'timestamp'}} != 1)  {
269                 &main::daemon_log("$session_id ERROR: xml tag 'timestamp' has no content or exists more than one time, ".
270                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
271                 &ymain::daemon_log($msg, 1);
272                 return;
273         }
274         if (not exists $msg_hash->{'macaddress'}){
275                 &main::daemon_log("$session_id ERROR: message does not contain needed xml tag 'mac_address', ".
276                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
277                 &main::daemon_log($msg, 1);
278                 return;
279         }
280         if (@{$msg_hash->{'macaddress'}} != 1)  {
281                 &main::daemon_log("$session_id ERROR: xml tag 'macaddress' has no content or exists more than one time, ".
282                                                 "setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
283                 &ymain::daemon_log($msg, 1);
284                 return;
285         }
287         # Fetch needed parameter
288         my $mac =  @{$msg_hash->{'macaddress'}}[0];
289         my $timestamp = @{$msg_hash->{'timestamp'}}[0];
290         
291         # Prepare login list
292         my @login_list = split(' ', @{$msg_hash->{$header}}[0] );
293     @login_list = &main::del_doubles(@login_list);
295         # Sanity check of login list
296         if (@login_list == 0) {
297                 # TODO
298                 return;
299         }
301         # Fetch ldap handle
302         my $ldap_handle = &main::get_ldap_handle();
304         # Get system info
305         my $ldap_mesg= $ldap_handle->search(
306                                         base => $main::ldap_base,
307                                         scope => 'sub',
308                                         filter => "macAddress=$mac",
309                                         );
310         if ($ldap_mesg->count == 0) {
311                 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
312                                                 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
313                 return;
314         }
316         my $ldap_entry = $ldap_mesg->pop_entry();
317         my $system_dn = $ldap_entry->dn();
318         
319         # For each logged in user set gotoLastSystem and gotoLastSystemLogin
320         foreach my $user (@login_list) {
321                 # Search user
322                 my $ldap_mesg= $ldap_handle->search(
323                                                 base => $main::ldap_base,
324                                                 scope => 'sub',
325                                                 filter => "uid=$user",
326                                                 );
327                 # Sanity check of user search
328                 if ($ldap_mesg->count == 0) {
329                         &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
330                                                         $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
332                 # Set gotoLastSystem and gotoLastSystemLogin
333                 } else {
334                         my $ldap_entry= $ldap_mesg->pop_entry();
335             my $do_update = 0;
337             # Set gotoLastSystem information
338             my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
339             if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
340                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
341             } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
342                 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
343                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
344                 $do_update++;
345             } else {
346                 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
347                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
348                 $do_update++;
349             }
351             # Set gotoLastSystemLogin information
352             # Attention: only write information if last_system_dn and system_dn differs
353             my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
354             if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
355                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
356             } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
357                 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
358                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
359                 $do_update++;
360             } else {
361                 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
362                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
363                 $do_update++;
364             }
366             if ($do_update) {
367                 my $result = $ldap_entry->update($ldap_handle);
368                 if ($result->code() != 0) {
369                     &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
370                             $result->{'errorMessage'}."\n".
371                             "\tbase: $main::ldap_base\n".
372                             "\tscope: 'sub'\n".
373                             "\tfilter: 'uid=$user'\n".
374                             "\tmessage: $msg", 1); 
375                 }
376             }
377                 }
378         }
380         return;
384 ## @method GOTOACTIVATION()
385 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
386 # @param msg - STRING - xml message with tag 'macaddress'
387 # @param msg_hash - HASHREF - message information parsed into a hash
388 # @param session_id - INTEGER - POE session id of the processing of this message
389 sub GOTOACTIVATION {
390     my ($msg, $msg_hash, $session_id) = @_;
391     my $header = @{$msg_hash->{'header'}}[0];
392     my $source = @{$msg_hash->{'source'}}[0];
393     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
395     # test whether content is an empty hash or a string which is required
396     my $content = @{$msg_hash->{$header}}[0];
397     if(ref($content) eq "HASH") { $content = ""; }
399     # clean up header
400     $header =~ s/CLMSG_//g;
402     my $sql_statement = "UPDATE $main::job_queue_tn ".
403             "SET progress='goto-activation', modified='1' ".
404             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
405     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
406     my $res = $main::job_db->update_dbentry($sql_statement);
407     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
408     return; 
412 ## @method PROGRESS()
413 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
414 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
415 # @param msg_hash - HASHREF - message information parsed into a hash
416 # @param session_id - INTEGER - POE session id of the processing of this message
417 sub PROGRESS {
418     my ($msg, $msg_hash, $session_id) = @_;
419     my $header = @{$msg_hash->{'header'}}[0];
420     my $source = @{$msg_hash->{'source'}}[0];
421     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
423     # test whether content is an empty hash or a string which is required
424     my $content = @{$msg_hash->{$header}}[0];
425     if(ref($content) eq "HASH") { $content = ""; }
427     # clean up header
428     $header =~ s/CLMSG_//g;
430     my $sql_statement = "UPDATE $main::job_queue_tn ".
431         "SET progress='$content', modified='1' ".
432         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
433     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
434     my $res = $main::job_db->update_dbentry($sql_statement);
435     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
437     return;
441 ## @method FAIREBOOT()
442 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
443 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
444 # @param msg_hash - HASHREF - message information parsed into a hash
445 # @param session_id - INTEGER - POE session id of the processing of this message
446 sub FAIREBOOT {
447     my ($msg, $msg_hash, $session_id) = @_;
448     my $header = @{$msg_hash->{'header'}}[0];
449     my $source = @{$msg_hash->{'source'}}[0];
450     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
452     # test whether content is an empty hash or a string which is required
453         my $content = @{$msg_hash->{$header}}[0];
454     if(ref($content) eq "HASH") { $content = ""; }
456     # clean up header
457     $header =~ s/CLMSG_//g;
459     my $sql_statement = "UPDATE $main::job_queue_tn ".
460             "SET result='$header "."$content', modified='1' ".
461             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
462     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
463     my $res = $main::job_db->update_dbentry($sql_statement);
464     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
466     return; 
470 ## @method TASKSKIP()
471 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
472 # @param msg - STRING - xml message with tag 'macaddress'.
473 # @param msg_hash - HASHREF - message information parsed into a hash
474 # @param session_id - INTEGER - POE session id of the processing of this message
475 sub TASKSKIP {
476     my ($msg, $msg_hash, $session_id) = @_;
477     my $header = @{$msg_hash->{'header'}}[0];
478     my $source = @{$msg_hash->{'source'}}[0];
479     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
481     # test whether content is an empty hash or a string which is required
482         my $content = @{$msg_hash->{$header}}[0];
483     if(ref($content) eq "HASH") { $content = ""; }
485     # clean up header
486     $header =~ s/CLMSG_//g;
488     my $sql_statement = "UPDATE $main::job_queue_tn ".
489             "SET result='$header "."$content', modified='1' ".
490             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
491     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
492     my $res = $main::job_db->update_dbentry($sql_statement);
493     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
495     return; 
499 ## @method TASKBEGIN()
500 # @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. 
501 # @param msg - STRING - xml message with tag 'macaddress'.
502 # @param msg_hash - HASHREF - message information parsed into a hash
503 # @param session_id - INTEGER - POE session id of the processing of this message
504 sub TASKBEGIN {
505     my ($msg, $msg_hash, $session_id) = @_;
506     my $header = @{$msg_hash->{'header'}}[0];
507     my $source = @{$msg_hash->{'source'}}[0];
508     my $target = @{$msg_hash->{'target'}}[0];
509     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
511     # test whether content is an empty hash or a string which is required
512         my $content = @{$msg_hash->{$header}}[0];
513     if(ref($content) eq "HASH") { $content = ""; }
515     # clean up header
516     $header =~ s/CLMSG_//g;
518     # TASKBEGIN eq finish or faiend 
519     if (($content eq 'finish') 
520                         || ($content eq 'faiend')
521                         || ($content eq 'savelog')
522                         ) {
523         my $sql_statement = "UPDATE $main::job_queue_tn ".
524             "SET status='done', result='$header "."$content', modified='1' ".
525             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
526         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
527         my $res = $main::job_db->update_dbentry($sql_statement);
528         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
529         
530         # set fai_state to localboot
531         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
533         # TASKBEGIN eq chboot
534         } elsif (($content eq 'chboot')
535                 || ($content eq 'tests')
536                 || ($content eq 'confdir')
537                 ) {
538                 # just ignor this client message
539                 # do nothing
541         # other TASKBEGIN msgs
542     } else {
543                 
544                 # TASKBEGIN msgs do only occour during a softupdate or a reinstallation 
545                 # of a host. Set all waiting update- or reinstall-jobs for host to 
546                 # processing so they can be handled correctly by the rest of the function. 
547                 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
548                 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')";  
549                 &main::daemon_log("$session_id DEBUB: $waiting_sql", 7); 
550                 my $waiting_res = $main::job_db->update_dbentry($waiting_sql); 
552                 # select processing jobs for host
553                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
554                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
555                 my $res = $main::job_db->select_dbentry($sql_statement);
557                 # there is exactly one job entry in queue for this host
558                 if (keys(%$res) == 1) {
559                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
560                         my $sql_statement = "UPDATE $main::job_queue_tn ".
561                 "SET result='$header $content', modified='1', siserver='localhost' ".
562                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
563                         my $err = $main::job_db->update_dbentry($sql_statement);
564                         if (not defined  $err) {
565                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
566                         }
567                         
568                 # there is no entry or more than one enties
569                 } else {
570                         # in case of more than one running jobs in queue, delete all jobs
571                         if (keys(%$res) > 1) {
572                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
573                                                                 "delete entries", 7); 
575                 # set job to status 'done', job will be deleted automatically
576                 my $sql_statement = "UPDATE $main::job_queue_tn ".
577                     "SET status='done', modified='1'".
578                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
579                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
580                 my $res = $main::job_db->update_dbentry( $sql_statement );
582                         }
583                 
584                         # in case of no and more than one running jobs in queue, add one single job
585                         # resolve plain name for host $macaddress
586                         my $plain_name;
587                         my $ldap_handle = &main::get_ldap_handle($session_id);
588                         if( not defined $ldap_handle ) {
589                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
590                                 $plain_name = "none";
592                         # try to fetch a 'real name'
593                         } else {
594                                 my $mesg = $ldap_handle->search(
595                                                 base => $main::ldap_base,
596                                                 scope => 'sub',
597                                                 attrs => ['cn'],
598                                                 filter => "(macAddress=$macaddress)");
599                                 if($mesg->code) {
600                                         &main::daemon_log($mesg->error, 1);
601                                         $plain_name = "none";
602                                 } else {
603                                         my $entry= $mesg->entry(0);
604                                         $plain_name = $entry->get_value("cn");
605                                 }
606                         }
608             # In any case add a new job to job queue
609                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
610                         my $func_dic = {table=>$main::job_queue_tn,
611                                         primkey=>['macaddress', 'headertag'],
612                                         timestamp=>&get_time,
613                                         status=>'processing',
614                                         result=>"$header $content",
615                                         progress=>'none',
616                                         headertag=>'trigger_action_reinstall',
617                                         targettag=>$target,
618                                         xmlmessage=>'none',
619                                         macaddress=>$macaddress,
620                                         plainname=>$plain_name,
621                     modified=>'1',
622                     siserver=>'localhost',
623                         };
624                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
625                         if ($err != 0)  {
626                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
627                         }
628                 }
629     }
631     return; 
635 ## @method TASKEND()
636 # @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. 
637 # @param msg - STRING - xml message with tag 'macaddress'.
638 # @param msg_hash - HASHREF - message information parsed into a hash
639 # @param session_id - INTEGER - POE session id of the processing of this message
640 sub TASKEND {
641     my ($msg, $msg_hash, $session_id) = @_;
642     my $header = @{$msg_hash->{'header'}}[0];
643     my $target = @{$msg_hash->{'target'}}[0];
644     my $source = @{$msg_hash->{'source'}}[0];
645     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
647     # test whether content is an empty hash or a string which is required
648     my $content = @{$msg_hash->{$header}}[0];
649     if(ref($content) eq "HASH") { $content = ""; }
651     # clean up header
652     $header =~ s/CLMSG_//g;
654         if ($content eq "savelog 0") {
655                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
656         
657         # set job to status 'done', job will be deleted automatically
658         my $sql_statement = "UPDATE $main::job_queue_tn ".
659                                         "SET status='done', modified='1'".
660                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
661         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
662         my $res = $main::job_db->update_dbentry( $sql_statement );
664         } else {
665         my $sql_statement = "UPDATE $main::job_queue_tn ".
666             "SET result='$header "."$content', 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);
670         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
671         }
673     return; 
677 ## @method TASKERROR()
678 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
679 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
680 # @param msg_hash - HASHREF - message information parsed into a hash
681 # @param session_id - INTEGER - POE session id of the processing of this message
682 sub TASKERROR {
683     my ($msg, $msg_hash, $session_id) = @_;
684     my $header = @{$msg_hash->{'header'}}[0];
685     my $source = @{$msg_hash->{'source'}}[0];
686     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
688     # clean up header
689     $header =~ s/CLMSG_//g;
691     # test whether content is an empty hash or a string which is required
692     my $content = @{$msg_hash->{$header}}[0];
693     if(ref($content) eq "HASH") { $content = ""; } 
695         # set fai_state to localboot
696         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
697                 
698     my $sql_statement = "UPDATE $main::job_queue_tn ".
699             "SET result='$header "."$content', modified='1' ".
700             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
701     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
702     my $res = $main::job_db->update_dbentry($sql_statement);
703     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
705     return; 
709 ## @method HOOK()
710 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
711 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
712 # @param msg_hash - HASHREF - message information parsed into a hash
713 # @param session_id - INTEGER - POE session id of the processing of this message
714 sub HOOK {
715     my ($msg, $msg_hash, $session_id) = @_;
716     my $header = @{$msg_hash->{'header'}}[0];
717     my $source = @{$msg_hash->{'source'}}[0];
718     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
720     # clean up header
721     $header =~ s/CLMSG_//g;
723     # test whether content is an empty hash or a string which is required
724         my $content = @{$msg_hash->{$header}}[0];
725     if(not ref($content) eq "STRING") { $content = ""; }
727     my $sql_statement = "UPDATE $main::job_queue_tn ".
728             "SET result='$header "."$content', modified='1' ".
729             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
730     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
731     my $res = $main::job_db->update_dbentry($sql_statement);
732     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
734     return;
738 =pod
740 =head1 NAME
742 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
744 =head1 SYNOPSIS
746  use GOSA::GosaSupportDaemon;
747  use MIME::Base64;
749 =head1 DESCRIPTION
751 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
753 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
755 =head1 METHODS
757 =over 4
759 =item get_events ( )
761 =item confirm_usr_msg ( )
763 =item PROGRESS ( )
765 =item FAIREBOOT ( )
767 =item TASKSKIP ( )
769 =item TASKBEGIN ( )
771 =item TASKEND ( )
773 =item TASKERROR ( )
775 =item HOOK ( )
777 =item GOTOACTIVATION ( )
779 =item LOGIN ( )
781 =item LOGOUT ( )
783 =item CURRENTLY_LOGGED_IN ( )
785 =item save_fai_log ( )
787 =back
789 =head1 BUGS
791 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>
793 =head1 COPYRIGHT
795 This code is part of GOsa (L<http://www.gosa-project.org>)
797 Copyright (C) 2003-2008 GONICUS GmbH
799 This program is distributed in the hope that it will be useful,
800 but WITHOUT ANY WARRANTY; without even the implied warranty of
801 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
802 GNU General Public License for more details.
804 =cut
807 1;