Code

clean up several files
[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.
4 # @author Andreas Rettenberger <rettenberger@gonicus.de> 
5 # @date 2008
6 # @version 1.0
8 package clMessages;
9 use Exporter;
10 @ISA = qw(Exporter);
11 my @events = (
12     "confirm_usr_msg",
13     "PROGRESS",
14     "FAIREBOOT",
15     "TASKSKIP",
16     "TASKBEGIN",
17     "TASKEND",
18     "TASKERROR",
19     "HOOK",
20     "GOTOACTIVATION",
21     "LOGIN",
22     "LOGOUT",
23     "CURRENTLY_LOGGED_IN",
24     "save_fai_log",
25     );
26 @EXPORT = @events;
28 use strict;
29 use warnings;
30 use Data::Dumper;
31 use GOSA::GosaSupportDaemon;
32 use MIME::Base64;
35 BEGIN {}
37 END {}
39 ### Start ######################################################################
41 # labled for deleting: rettenbe 20080730
42 #my $ldap_uri;
43 #my $ldap_base;
44 #my $ldap_admin_dn;
45 #my $ldap_admin_password;
46 #
47 #my %cfg_defaults = (
48 #"server" => {
49 #   "ldap-uri" => [\$ldap_uri, ""],
50 #   "ldap-base" => [\$ldap_base, ""],
51 #   "ldap-admin-dn" => [\$ldap_admin_dn, ""],
52 #   "ldap-admin-password" => [\$ldap_admin_password, ""],
53 #   },
54 #);
55 #&read_configfile($main::cfg_file, %cfg_defaults);
56 #
59 ## @method get_events()
60 # @details A brief function returning a list of functions which are exported by importing the module.
61 # @return List of all provided functions
62 sub get_events {
63     return \@events;
64 }
67 sub confirm_usr_msg {
68     my ($msg, $msg_hash, $session_id) = @_;
69     my $message = @{$msg_hash->{'message'}}[0];
70     my $subject = @{$msg_hash->{'subject'}}[0];
71     my $usr = @{$msg_hash->{'usr'}}[0];
73     # set update for this message
74     my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')"; 
75     &main::daemon_log("$session_id DEBUG: $sql", 7);
76     my $res = $main::messaging_db->exec_statement($sql); 
79     return;
80 }
84 #sub read_configfile {
85 #    my ($cfg_file, %cfg_defaults) = @_;
86 #    my $cfg;
87 #
88 #    if( defined( $cfg_file) && ( (-s $cfg_file) > 0 )) {
89 #        if( -r $cfg_file ) {
90 #            $cfg = Config::IniFiles->new( -file => $cfg_file );
91 #        } else {
92 #            &main::daemon_log("ERROR: clMessages.pm couldn't read config file!", 1);
93 #        }
94 #    } else {
95 #        $cfg = Config::IniFiles->new() ;
96 #    }
97 #    foreach my $section (keys %cfg_defaults) {
98 #        foreach my $param (keys %{$cfg_defaults{ $section }}) {
99 #            my $pinfo = $cfg_defaults{ $section }{ $param };
100 #            ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
101 #        }
102 #    }
103 #}
106 sub save_fai_log {
107     my ($msg, $msg_hash, $session_id) = @_;
108     my $header = @{$msg_hash->{'header'}}[0];
109     my $source = @{$msg_hash->{'source'}}[0];
110     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
111     my $all_logs = @{$msg_hash->{$header}}[0];
113     # if there is nothing to log
114     if( ref($all_logs) eq "HASH" ) { return; }
115         
116     my $client_fai_log_dir = $main::client_fai_log_dir;
117     if (not -d $client_fai_log_dir) {
118         mkdir($client_fai_log_dir, 0755)
119     }
121     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
122     if (not -d $client_fai_log_dir) {
123         mkdir($client_fai_log_dir, 0755)
124     }
126     my $time = &get_time;
127     $time = substr($time, 0, 8)."_".substr($time, 8, 6);
128     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
129     mkdir($client_fai_log_dir, 0755);
131     my @all_logs = split(/log_file:/, $all_logs); 
132     foreach my $log (@all_logs) {
133         if (length $log == 0) { next; };
134         my ($log_file, $log_string) = split(":", $log);
135         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
137         open(my $LOG_FILE, ">$client_fai_log_file"); 
138         print $LOG_FILE &decode_base64($log_string);
139         close($LOG_FILE);
141     }
142     return;
146 sub LOGIN {
147     my ($msg, $msg_hash, $session_id) = @_;
148     my $header = @{$msg_hash->{'header'}}[0];
149     my $source = @{$msg_hash->{'source'}}[0];
150     my $login = @{$msg_hash->{$header}}[0];
152     my %add_hash = ( table=>$main::login_users_tn, 
153         primkey=> ['client', 'user'],
154         client=>$source,
155         user=>$login,
156         timestamp=>&get_time,
157         ); 
158     my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
159     if ($res != 0)  {
160         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
161         return;
162     }
164     return;   
168 sub LOGOUT {
169     my ($msg, $msg_hash, $session_id) = @_;
170     my $header = @{$msg_hash->{'header'}}[0];
171     my $source = @{$msg_hash->{'source'}}[0];
172     my $login = @{$msg_hash->{$header}}[0];
173     
174     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
175     my $res =  $main::login_users_db->del_dbentry($sql_statement);
176     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
177     
178     return;
182 sub CURRENTLY_LOGGED_IN {
183     my ($msg, $msg_hash, $session_id) = @_;
184     my ($sql_statement, $db_res);
185     my $header = @{$msg_hash->{'header'}}[0];
186     my $source = @{$msg_hash->{'source'}}[0];
187     my $login = @{$msg_hash->{$header}}[0];
189     if(ref $login eq "HASH") { 
190         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
191         return;     
192     }
193     
194     # fetch all user currently assigned to the client at login_users_db
195     my %currently_logged_in_user = (); 
196     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
197     $db_res = $main::login_users_db->select_dbentry($sql_statement);
198     while( my($hit_id, $hit) = each(%{$db_res}) ) {
199         $currently_logged_in_user{$hit->{'user'}} = 1;
200     }
201     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
203     # update all reported users in login_user_db
204     my @logged_in_user = split(/\s+/, $login);
205     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
206     foreach my $user (@logged_in_user) {
207         my %add_hash = ( table=>$main::login_users_tn, 
208                 primkey=> ['client', 'user'],
209                 client=>$source,
210                 user=>$user,
211                 timestamp=>&get_time,
212                 ); 
213         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
214         if ($res != 0)  {
215             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
216             return;
217         }
219         delete $currently_logged_in_user{$user};
220     }
222     # if there is still a user in %currently_logged_in_user 
223     # although he is not reported by client 
224     # then delete it from $login_user_db
225     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
226         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
227                 "in at client '$source' but still found at login_user_db", 3); 
228         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
229         my $res =  $main::login_users_db->del_dbentry($sql_statement);
230         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
231     }
233     return;
237 sub GOTOACTIVATION {
238     my ($msg, $msg_hash, $session_id) = @_;
239     my $header = @{$msg_hash->{'header'}}[0];
240     my $source = @{$msg_hash->{'source'}}[0];
241     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
243     # test whether content is an empty hash or a string which is required
244     my $content = @{$msg_hash->{$header}}[0];
245     if(ref($content) eq "HASH") { $content = ""; }
247     # clean up header
248     $header =~ s/CLMSG_//g;
250     my $sql_statement = "UPDATE $main::job_queue_tn ".
251             "SET status='processing', progress='goto-activation', modified='1' ".
252             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
253     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
254     my $res = $main::job_db->update_dbentry($sql_statement);
255     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
256     return; 
260 sub PROGRESS {
261     my ($msg, $msg_hash, $session_id) = @_;
262     my $header = @{$msg_hash->{'header'}}[0];
263     my $source = @{$msg_hash->{'source'}}[0];
264     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
266     # test whether content is an empty hash or a string which is required
267     my $content = @{$msg_hash->{$header}}[0];
268     if(ref($content) eq "HASH") { $content = ""; }
270     # clean up header
271     $header =~ s/CLMSG_//g;
273     my $sql_statement = "UPDATE $main::job_queue_tn ".
274         "SET progress='$content', modified='1' ".
275         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
276     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
277     my $res = $main::job_db->update_dbentry($sql_statement);
278     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
280     return;
284 sub FAIREBOOT {
285     my ($msg, $msg_hash, $session_id) = @_;
286     my $header = @{$msg_hash->{'header'}}[0];
287     my $source = @{$msg_hash->{'source'}}[0];
288     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
290     # test whether content is an empty hash or a string which is required
291         my $content = @{$msg_hash->{$header}}[0];
292     if(ref($content) eq "HASH") { $content = ""; }
294     # clean up header
295     $header =~ s/CLMSG_//g;
297     my $sql_statement = "UPDATE $main::job_queue_tn ".
298             "SET status='processing', result='$header "."$content', modified='1' ".
299             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
300     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
301     my $res = $main::job_db->update_dbentry($sql_statement);
302     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
304     return; 
308 sub TASKSKIP {
309     my ($msg, $msg_hash, $session_id) = @_;
310     my $header = @{$msg_hash->{'header'}}[0];
311     my $source = @{$msg_hash->{'source'}}[0];
312     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
314     # test whether content is an empty hash or a string which is required
315         my $content = @{$msg_hash->{$header}}[0];
316     if(ref($content) eq "HASH") { $content = ""; }
318     # clean up header
319     $header =~ s/CLMSG_//g;
321     my $sql_statement = "UPDATE $main::job_queue_tn ".
322             "SET status='processing', result='$header "."$content', modified='1' ".
323             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
324     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
325     my $res = $main::job_db->update_dbentry($sql_statement);
326     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
328     return; 
332 sub TASKBEGIN {
333     my ($msg, $msg_hash, $session_id) = @_;
334     my $header = @{$msg_hash->{'header'}}[0];
335     my $source = @{$msg_hash->{'source'}}[0];
336     my $target = @{$msg_hash->{'target'}}[0];
337     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
339     # test whether content is an empty hash or a string which is required
340         my $content = @{$msg_hash->{$header}}[0];
341     if(ref($content) eq "HASH") { $content = ""; }
343     # clean up header
344     $header =~ s/CLMSG_//g;
346     # TASKBEGIN eq finish or faiend 
347     if (($content eq 'finish') 
348                         || ($content eq 'faiend')
349                         || ($content eq 'savelog')
350                         ) {
351         my $sql_statement = "UPDATE $main::job_queue_tn ".
352             "SET status='done', result='$header "."$content', modified='1' ".
353             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
354         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
355         my $res = $main::job_db->update_dbentry($sql_statement);
356         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
357         
358         # set fai_state to localboot
359         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
361         # TASKBEGIN eq chboot
362         } elsif (($content eq 'chboot')
363                 || ($content eq 'test')
364                 || ($content eq 'confdir')
365                 ) {
366                 # just ignor this client message
367                 # do nothing
369         # other TASKBEGIN msgs
370     } else {
371                 # select processing jobs for host
372                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
373                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
374                 my $res = $main::job_db->select_dbentry($sql_statement);
376                 # there is exactly one job entry in queue for this host
377                 if (keys(%$res) == 1) {
378                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
379                         my $sql_statement = "UPDATE $main::job_queue_tn ".
380                 "SET result='$header $content', modified='1' ".
381                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
382                         my $err = $main::job_db->update_dbentry($sql_statement);
383                         if (not defined  $err) {
384                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
385                         }
386                         
387                 # there is no entry or more than one enties
388                 } else {
389                         # in case of more than one running jobs in queue, delete all jobs
390                         if (keys(%$res) > 1) {
391                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
392                                                                 "delete entries", 7); 
394                 # set job to status 'done', job will be deleted automatically
395                 my $sql_statement = "UPDATE $main::job_queue_tn ".
396                     "SET status='done', modified='1'".
397                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
398                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
399                 my $res = $main::job_db->update_dbentry( $sql_statement );
401                         }
402                 
403                         # in case of no and more than one running jobs in queue, add one single job
404                         # resolve plain name for host $macaddress
405                         my $plain_name;
406                         my $ldap_handle = &main::get_ldap_handle($session_id);
407                         if( not defined $ldap_handle ) {
408                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
409                                 $plain_name = "none";
411                         # try to fetch a 'real name'
412                         } else {
413                                 my $mesg = $ldap_handle->search(
414                                                 base => $main::ldap_base,
415                                                 scope => 'sub',
416                                                 attrs => ['cn'],
417                                                 filter => "(macAddress=$macaddress)");
418                                 if($mesg->code) {
419                                         &main::daemon_log($mesg->error, 1);
420                                         $plain_name = "none";
421                                 } else {
422                                         my $entry= $mesg->entry(0);
423                                         $plain_name = $entry->get_value("cn");
424                                 }
425                         }
428                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
429                         my $func_dic = {table=>$main::job_queue_tn,
430                                         primkey=>['macaddress', 'headertag'],
431                                         timestamp=>&get_time,
432                                         status=>'processing',
433                                         result=>"$header $content",
434                                         progress=>'none',
435                                         headertag=>'trigger_action_reinstall',
436                                         targettag=>$target,
437                                         xmlmessage=>'none',
438                                         macaddress=>$macaddress,
439                                         plainname=>$plain_name,
440                     modified=>'1',
441                     siserver=>$source,
442                         };
443                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
444                         if ($err != 0)  {
445                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
446                         }
448                 }
450 # -----------------------> Update hier
451 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
452 #  <header>CLMSG_TASKBEGIN</header>
453 # macaddress auslesen, Client im LDAP lokalisieren
454 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
455     }
457     return; 
461 sub TASKEND {
462     my ($msg, $msg_hash, $session_id) = @_;
463     my $header = @{$msg_hash->{'header'}}[0];
464     my $target = @{$msg_hash->{'target'}}[0];
465     my $source = @{$msg_hash->{'source'}}[0];
466     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
468     # test whether content is an empty hash or a string which is required
469     my $content = @{$msg_hash->{$header}}[0];
470     if(ref($content) eq "HASH") { $content = ""; }
472     # clean up header
473     $header =~ s/CLMSG_//g;
475         if ($content eq "savelog 0") {
476                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
477         
478         # set job to status 'done', job will be deleted automatically
479         my $sql_statement = "UPDATE $main::job_queue_tn ".
480                                         "SET status='done', modified='1'".
481                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
482         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
483         my $res = $main::job_db->update_dbentry( $sql_statement );
485         } else {
486         my $sql_statement = "UPDATE $main::job_queue_tn ".
487             "SET status='processing', result='$header "."$content', modified='1' ".
488             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
489         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
490         my $res = $main::job_db->update_dbentry($sql_statement);
491         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
492         }
494     return; 
498 sub TASKERROR {
499     my ($msg, $msg_hash, $session_id) = @_;
500     my $header = @{$msg_hash->{'header'}}[0];
501     my $source = @{$msg_hash->{'source'}}[0];
502     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
504     # clean up header
505     $header =~ s/CLMSG_//g;
507     # test whether content is an empty hash or a string which is required
508     my $content = @{$msg_hash->{$header}}[0];
509     if(ref($content) eq "HASH") { $content = ""; } 
511         # set fai_state to localboot
512         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
513                 
514     my $sql_statement = "UPDATE $main::job_queue_tn ".
515             "SET status='processing', result='$header "."$content', modified='1' ".
516             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
517     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
518     my $res = $main::job_db->update_dbentry($sql_statement);
519     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
521 # -----------------------> Update hier
522 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
523 #  <header>CLMSG_TASKBEGIN</header>
524 # macaddress auslesen, Client im LDAP lokalisieren
525 # FAIstate auf "error" setzen
527     return; 
531 sub HOOK {
532     my ($msg, $msg_hash, $session_id) = @_;
533     my $header = @{$msg_hash->{'header'}}[0];
534     my $source = @{$msg_hash->{'source'}}[0];
535     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
537     # clean up header
538     $header =~ s/CLMSG_//g;
540     # test whether content is an empty hash or a string which is required
541         my $content = @{$msg_hash->{$header}}[0];
542     if(not ref($content) eq "STRING") { $content = ""; }
544     my $sql_statement = "UPDATE $main::job_queue_tn ".
545             "SET status='processing', result='$header "."$content', modified='1' ".
546             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
547     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
548     my $res = $main::job_db->update_dbentry($sql_statement);
549     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
551     return;
555 1;