Code

new ldap handling, a handle is taken out of a pool of ldap handles and given back...
[gosa.git] / gosa-si / server / events / clMessages.pm
1 ## @file
2 # @brief Implementation of a GOsa-SI event module. 
3 # @details A GOsa-SI event module containing all functions to handle incoming messages from clients.
5 package clMessages;
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, $ldap_handle) = @_;
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         $res = &set_last_system($msg, $msg_hash, $session_id, $ldap_handle);
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, $ldap_handle) = @_;
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         my $res = &set_last_system($msg, $msg_hash, $session_id, $ldap_handle);
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, $ldap_handle) = @_;
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         # Get system info
310         my $ldap_mesg= $ldap_handle->search(
311                                         base => $main::ldap_base,
312                                         scope => 'sub',
313                                         filter => "macAddress=$mac",
314                                         );
315         if ($ldap_mesg->count == 0) {
316                 &main::daemon_log("$session_id ERROR: no system with mac address='$mac' was found in base '".
317                                                 $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
318                 return;
319         }
321         my $ldap_entry = $ldap_mesg->pop_entry();
322         my $system_dn = $ldap_entry->dn();
323         
324         # For each logged in user set gotoLastSystem and gotoLastSystemLogin
325         foreach my $user (@login_list) {
326                 # Search user
327                 my $ldap_mesg= $ldap_handle->search(
328                                                 base => $main::ldap_base,
329                                                 scope => 'sub',
330                                                 filter => "uid=$user",
331                                                 );
332                 # Sanity check of user search
333                 if ($ldap_mesg->count == 0) {
334                         &main::daemon_log("$session_id ERROR: no user with uid='$user' was found in base '".
335                                                         $main::ldap_base."', setting of 'gotoLastSystem' and 'gotoLastSystemLogin' stopped!", 1);
337                 # Set gotoLastSystem and gotoLastSystemLogin
338                 } else {
339                         my $ldap_entry= $ldap_mesg->pop_entry();
340             my $do_update = 0;
342             # Set gotoLastSystem information
343             my $last_system_dn = $ldap_entry->get_value('gotoLastSystem');
344             if ((defined $last_system_dn) && ($last_system_dn eq $system_dn)) {
345                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystem' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
346             } elsif ((defined $last_system_dn) && ($last_system_dn ne $system_dn)) {
347                 $ldap_entry->replace ( 'gotoLastSystem' => $system_dn );
348                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!",5);
349                 $do_update++;
350             } else {
351                 $ldap_entry->add( 'gotoLastSystem' => $system_dn );
352                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystem'='$system_dn' at ldap entry 'uid=$user'!", 5);
353                 $do_update++;
354             }
356             # Set gotoLastSystemLogin information
357             # Attention: only write information if last_system_dn and system_dn differs
358             my $last_system_login = $ldap_entry->get_value('gotoLastSystemLogin');
359             if ((defined $last_system_login) && ($last_system_dn eq $system_dn)) {
360                 &main::daemon_log("$session_id INFO: no new 'gotoLastSystemLogin' inforamtion for ladp entry 'uid=$user', do nothing!", 5);
361             } elsif ((defined $last_system_login) && ($last_system_dn ne $system_dn)) {
362                 $ldap_entry->replace ( 'gotoLastSystemLogin' => $timestamp );
363                 &main::daemon_log("$session_id INFO: update attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!", 5);
364                 $do_update++;
365             } else {
366                 $ldap_entry->add( 'gotoLastSystemLogin' => $timestamp );
367                 &main::daemon_log("$session_id INFO: add attribute 'gotoLastSystemLogin'='$timestamp' at ldap entry 'uid=$user'!",5);
368                 $do_update++;
369             }
371             if ($do_update) {
372                 my $result = $ldap_entry->update($ldap_handle);
373                 if ($result->code() != 0) {
374                     &main::daemon_log("$session_id ERROR: setting 'gotoLastSystem' and 'gotoLastSystemLogin' at user '$user' failed: ".
375                             $result->{'errorMessage'}."\n".
376                             "\tbase: $main::ldap_base\n".
377                             "\tscope: 'sub'\n".
378                             "\tfilter: 'uid=$user'\n".
379                             "\tmessage: $msg", 1); 
380                 }
381             }
382                 }
383         }
385         return;
389 ## @method GOTOACTIVATION()
390 # @details Client is set at job_queue_db to status 'processing' and 'modified'.
391 # @param msg - STRING - xml message with tag 'macaddress'
392 # @param msg_hash - HASHREF - message information parsed into a hash
393 # @param session_id - INTEGER - POE session id of the processing of this message
394 sub GOTOACTIVATION {
395     my ($msg, $msg_hash, $session_id) = @_;
396     my $header = @{$msg_hash->{'header'}}[0];
397     my $source = @{$msg_hash->{'source'}}[0];
398     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
400     # test whether content is an empty hash or a string which is required
401     my $content = @{$msg_hash->{$header}}[0];
402     if(ref($content) eq "HASH") { $content = ""; }
404     # clean up header
405     $header =~ s/CLMSG_//g;
407     my $sql_statement = "UPDATE $main::job_queue_tn ".
408             "SET progress='goto-activation', modified='1' ".
409             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
410     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
411     my $res = $main::job_db->update_dbentry($sql_statement);
412     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
413     return; 
417 ## @method PROGRESS()
418 # @details Message reports installation progress of the client. Installation job at job_queue_db is going to be updated.
419 # @param msg - STRING - xml message with tags 'macaddress' and 'PROGRESS'
420 # @param msg_hash - HASHREF - message information parsed into a hash
421 # @param session_id - INTEGER - POE session id of the processing of this message
422 sub PROGRESS {
423     my ($msg, $msg_hash, $session_id) = @_;
424     my $header = @{$msg_hash->{'header'}}[0];
425     my $source = @{$msg_hash->{'source'}}[0];
426     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
428     # test whether content is an empty hash or a string which is required
429     my $content = @{$msg_hash->{$header}}[0];
430     if(ref($content) eq "HASH") { $content = ""; }
432     # clean up header
433     $header =~ s/CLMSG_//g;
435     my $sql_statement = "UPDATE $main::job_queue_tn ".
436         "SET progress='$content', modified='1' ".
437         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
438     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
439     my $res = $main::job_db->update_dbentry($sql_statement);
440     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
442     return;
446 ## @method FAIREBOOT()
447 # @details Message reports a FAI reboot. Job at job_queue_db is going to be updated.
448 # @param msg - STRING - xml message with tag 'macaddress' and 'FAIREBOOT'
449 # @param msg_hash - HASHREF - message information parsed into a hash
450 # @param session_id - INTEGER - POE session id of the processing of this message
451 sub FAIREBOOT {
452     my ($msg, $msg_hash, $session_id) = @_;
453     my $header = @{$msg_hash->{'header'}}[0];
454     my $source = @{$msg_hash->{'source'}}[0];
455     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
457     # test whether content is an empty hash or a string which is required
458         my $content = @{$msg_hash->{$header}}[0];
459     if(ref($content) eq "HASH") { $content = ""; }
461     # clean up header
462     $header =~ s/CLMSG_//g;
464     my $sql_statement = "UPDATE $main::job_queue_tn ".
465             "SET result='$header "."$content', modified='1' ".
466             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
467     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
468     my $res = $main::job_db->update_dbentry($sql_statement);
469     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
471     return; 
475 ## @method TASKSKIP()
476 # @details Message reports a skipped FAI task. Job at job_queue_db is going to be updated. 
477 # @param msg - STRING - xml message with tag 'macaddress'.
478 # @param msg_hash - HASHREF - message information parsed into a hash
479 # @param session_id - INTEGER - POE session id of the processing of this message
480 sub TASKSKIP {
481     my ($msg, $msg_hash, $session_id) = @_;
482     my $header = @{$msg_hash->{'header'}}[0];
483     my $source = @{$msg_hash->{'source'}}[0];
484     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
486     # test whether content is an empty hash or a string which is required
487         my $content = @{$msg_hash->{$header}}[0];
488     if(ref($content) eq "HASH") { $content = ""; }
490     # clean up header
491     $header =~ s/CLMSG_//g;
493     my $sql_statement = "UPDATE $main::job_queue_tn ".
494             "SET result='$header "."$content', modified='1' ".
495             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
496     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
497     my $res = $main::job_db->update_dbentry($sql_statement);
498     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
500     return; 
504 ## @method TASKBEGIN()
505 # @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. 
506 # @param msg - STRING - xml message with tag 'macaddress'.
507 # @param msg_hash - HASHREF - message information parsed into a hash
508 # @param session_id - INTEGER - POE session id of the processing of this message
509 sub TASKBEGIN {
510     my ($msg, $msg_hash, $session_id, $ldap_handle) = @_;
511     my $header = @{$msg_hash->{'header'}}[0];
512     my $source = @{$msg_hash->{'source'}}[0];
513     my $target = @{$msg_hash->{'target'}}[0];
514     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
516     # test whether content is an empty hash or a string which is required
517         my $content = @{$msg_hash->{$header}}[0];
518     if(ref($content) eq "HASH") { $content = ""; }
520     # clean up header
521     $header =~ s/CLMSG_//g;
523     # TASKBEGIN eq finish or faiend 
524     if (($content eq 'finish') 
525                         || ($content eq 'faiend')
526                         || ($content eq 'savelog')
527                         ) {
528         my $sql_statement = "UPDATE $main::job_queue_tn ".
529             "SET status='done', result='$header "."$content', modified='1' ".
530             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
531         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
532         my $res = $main::job_db->update_dbentry($sql_statement);
533         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
534         
535         # set fai_state to localboot
536         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
538         # TASKBEGIN eq chboot
539         } elsif (($content eq 'chboot')
540                 || ($content eq 'test')
541                 || ($content eq 'confdir')
542                 ) {
543                 # just ignor this client message
544                 # do nothing
546         # other TASKBEGIN msgs
547     } else {
548                 # select processing jobs for host
549                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
550                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
551                 my $res = $main::job_db->select_dbentry($sql_statement);
553                 # there is exactly one job entry in queue for this host
554                 if (keys(%$res) == 1) {
555                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
556                         my $sql_statement = "UPDATE $main::job_queue_tn ".
557                 "SET result='$header $content', modified='1', siserver='localhost' ".
558                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
559                         my $err = $main::job_db->update_dbentry($sql_statement);
560                         if (not defined  $err) {
561                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
562                         }
563                         
564                 # there is no entry or more than one enties
565                 } else {
566                         # in case of more than one running jobs in queue, delete all jobs
567                         if (keys(%$res) > 1) {
568                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
569                                                                 "delete entries", 7); 
571                 # set job to status 'done', job will be deleted automatically
572                 my $sql_statement = "UPDATE $main::job_queue_tn ".
573                     "SET status='done', modified='1'".
574                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
575                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
576                 my $res = $main::job_db->update_dbentry( $sql_statement );
578                         }
579                 
580                         # in case of no and more than one running jobs in queue, add one single job
581                         # resolve plain name for host $macaddress
582                         my $plain_name;
583                         my $mesg = $ldap_handle->search(
584                                         base => $main::ldap_base,
585                                         scope => 'sub',
586                                         attrs => ['cn'],
587                                         filter => "(macAddress=$macaddress)");
588                         if(not $mesg->code) {
589                                 my $entry= $mesg->entry(0);
590                                 $plain_name = $entry->get_value("cn");
591                         } else {
592                                 &main::daemon_log($mesg->error, 1);
593                                 $plain_name = "none";
594                         }
596             # In any case add a new job to job queue
597                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
598                         my $func_dic = {table=>$main::job_queue_tn,
599                                         primkey=>['macaddress', 'headertag'],
600                                         timestamp=>&get_time,
601                                         status=>'processing',
602                                         result=>"$header $content",
603                                         progress=>'none',
604                                         headertag=>'trigger_action_reinstall',
605                                         targettag=>$target,
606                                         xmlmessage=>'none',
607                                         macaddress=>$macaddress,
608                                         plainname=>$plain_name,
609                     modified=>'1',
610                     siserver=>'localhost',
611                         };
612                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
613                         if ($err != 0)  {
614                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
615                         }
616                 }
617     }
619     return; 
623 ## @method TASKEND()
624 # @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. 
625 # @param msg - STRING - xml message with tag 'macaddress'.
626 # @param msg_hash - HASHREF - message information parsed into a hash
627 # @param session_id - INTEGER - POE session id of the processing of this message
628 sub TASKEND {
629     my ($msg, $msg_hash, $session_id) = @_;
630     my $header = @{$msg_hash->{'header'}}[0];
631     my $target = @{$msg_hash->{'target'}}[0];
632     my $source = @{$msg_hash->{'source'}}[0];
633     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
635     # test whether content is an empty hash or a string which is required
636     my $content = @{$msg_hash->{$header}}[0];
637     if(ref($content) eq "HASH") { $content = ""; }
639     # clean up header
640     $header =~ s/CLMSG_//g;
642         if ($content eq "savelog 0") {
643                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
644         
645         # set job to status 'done', job will be deleted automatically
646         my $sql_statement = "UPDATE $main::job_queue_tn ".
647                                         "SET status='done', modified='1'".
648                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
649         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
650         my $res = $main::job_db->update_dbentry( $sql_statement );
652         } else {
653         my $sql_statement = "UPDATE $main::job_queue_tn ".
654             "SET result='$header "."$content', modified='1' ".
655             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
656         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
657         my $res = $main::job_db->update_dbentry($sql_statement);
658         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
659         }
661     return; 
665 ## @method TASKERROR()
666 # @details Message reports a FAI error. Job at job_queue_db is going to be updated. 
667 # @param msg - STRING - xml message with tag 'macaddress' and 'TASKERROR'
668 # @param msg_hash - HASHREF - message information parsed into a hash
669 # @param session_id - INTEGER - POE session id of the processing of this message
670 sub TASKERROR {
671     my ($msg, $msg_hash, $session_id) = @_;
672     my $header = @{$msg_hash->{'header'}}[0];
673     my $source = @{$msg_hash->{'source'}}[0];
674     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
676     # clean up header
677     $header =~ s/CLMSG_//g;
679     # test whether content is an empty hash or a string which is required
680     my $content = @{$msg_hash->{$header}}[0];
681     if(ref($content) eq "HASH") { $content = ""; } 
683         # set fai_state to localboot
684         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
685                 
686     my $sql_statement = "UPDATE $main::job_queue_tn ".
687             "SET result='$header "."$content', modified='1' ".
688             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
689     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
690     my $res = $main::job_db->update_dbentry($sql_statement);
691     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
693     return; 
697 ## @method HOOK()
698 # @details Message reports a FAI hook. Job at job_queue_db is going to be updated. 
699 # @param msg - STRING - xml message with tag 'macaddress' and 'HOOK'
700 # @param msg_hash - HASHREF - message information parsed into a hash
701 # @param session_id - INTEGER - POE session id of the processing of this message
702 sub HOOK {
703     my ($msg, $msg_hash, $session_id) = @_;
704     my $header = @{$msg_hash->{'header'}}[0];
705     my $source = @{$msg_hash->{'source'}}[0];
706     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
708     # clean up header
709     $header =~ s/CLMSG_//g;
711     # test whether content is an empty hash or a string which is required
712         my $content = @{$msg_hash->{$header}}[0];
713     if(not ref($content) eq "STRING") { $content = ""; }
715     my $sql_statement = "UPDATE $main::job_queue_tn ".
716             "SET result='$header "."$content', modified='1' ".
717             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
718     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
719     my $res = $main::job_db->update_dbentry($sql_statement);
720     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
722     return;
726 =pod
728 =head1 NAME
730 clMessages - Implementation of a GOsa-SI event module for GOsa-SI-server.
732 =head1 SYNOPSIS
734  use GOSA::GosaSupportDaemon;
735  use MIME::Base64;
737 =head1 DESCRIPTION
739 This GOsa-SI event module containing all functions to handle messages coming from GOsa-SI-clients. 
741 This module will be automatically imported by GOsa-SI if it is under F</usr/lib/gosa-si/server/E<lt>PACKAGEMODULEE<gt>/> .
743 =head1 METHODS
745 =over 4
747 =item get_events ( )
749 =item confirm_usr_msg ( )
751 =item PROGRESS ( )
753 =item FAIREBOOT ( )
755 =item TASKSKIP ( )
757 =item TASKBEGIN ( )
759 =item TASKEND ( )
761 =item TASKERROR ( )
763 =item HOOK ( )
765 =item GOTOACTIVATION ( )
767 =item LOGIN ( )
769 =item LOGOUT ( )
771 =item CURRENTLY_LOGGED_IN ( )
773 =item save_fai_log ( )
775 =back
777 =head1 BUGS
779 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>
781 =head1 COPYRIGHT
783 This code is part of GOsa (L<http://www.gosa-project.org>)
785 Copyright (C) 2003-2008 GONICUS GmbH
787 This program is distributed in the hope that it will be useful,
788 but WITHOUT ANY WARRANTY; without even the implied warranty of
789 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
790 GNU General Public License for more details.
792 =cut
795 1;