Code

Added simple locale extractor
[gosa.git] / gosa-si / server / events / clMessages.pm
1 package clMessages;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5     "confirm_usr_msg",
6     "PROGRESS",
7     "FAIREBOOT",
8     "TASKSKIP",
9     "TASKBEGIN",
10     "TASKEND",
11     "TASKERROR",
12     "HOOK",
13     "GOTOACTIVATION",
14     "LOGIN",
15     "LOGOUT",
16     "CURRENTLY_LOGGED_IN",
17     "save_fai_log",
18     );
19 @EXPORT = @events;
21 use strict;
22 use warnings;
23 use Data::Dumper;
24 use GOSA::GosaSupportDaemon;
25 use MIME::Base64;
28 BEGIN {}
30 END {}
32 ### Start ######################################################################
34 my $ldap_uri;
35 my $ldap_base;
36 my $ldap_admin_dn;
37 my $ldap_admin_password;
39 my %cfg_defaults = (
40 "server" => {
41    "ldap-uri" => [\$ldap_uri, ""],
42    "ldap-base" => [\$ldap_base, ""],
43    "ldap-admin-dn" => [\$ldap_admin_dn, ""],
44    "ldap-admin-password" => [\$ldap_admin_password, ""],
45    },
46 );
47 &read_configfile($main::cfg_file, %cfg_defaults);
50 sub get_events {
51     return \@events;
52 }
55 sub confirm_usr_msg {
56     my ($msg, $msg_hash, $session_id) = @_;
57     my $message = @{$msg_hash->{'message'}}[0];
58     my $subject = @{$msg_hash->{'subject'}}[0];
59     my $usr = @{$msg_hash->{'usr'}}[0];
61     # set update for this message
62     my $sql = "UPDATE $main::messaging_tn SET flag='s' WHERE (message='$message' AND subject='$subject' AND message_to='$usr')"; 
63     &main::daemon_log("$session_id DEBUG: $sql", 7);
64     my $res = $main::messaging_db->exec_statement($sql); 
67     return;
68 }
72 sub read_configfile {
73     my ($cfg_file, %cfg_defaults) = @_;
74     my $cfg;
76     if( defined( $cfg_file) && ( (-s $cfg_file) > 0 )) {
77         if( -r $cfg_file ) {
78             $cfg = Config::IniFiles->new( -file => $cfg_file );
79         } else {
80             &main::daemon_log("ERROR: clMessages.pm couldn't read config file!", 1);
81         }
82     } else {
83         $cfg = Config::IniFiles->new() ;
84     }
85     foreach my $section (keys %cfg_defaults) {
86         foreach my $param (keys %{$cfg_defaults{ $section }}) {
87             my $pinfo = $cfg_defaults{ $section }{ $param };
88             ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
89         }
90     }
91 }
94 sub save_fai_log {
95     my ($msg, $msg_hash, $session_id) = @_;
96     my $header = @{$msg_hash->{'header'}}[0];
97     my $source = @{$msg_hash->{'source'}}[0];
98     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
99     my $all_logs = @{$msg_hash->{$header}}[0];
101     # if there is nothing to log
102     if( ref($all_logs) eq "HASH" ) { return; }
103         
104     my $client_fai_log_dir = $main::client_fai_log_dir;
105     if (not -d $client_fai_log_dir) {
106         mkdir($client_fai_log_dir, 0755)
107     }
109     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
110     if (not -d $client_fai_log_dir) {
111         mkdir($client_fai_log_dir, 0755)
112     }
114     my $time = &get_time;
115     $time = substr($time, 0, 8)."_".substr($time, 8, 6);
116     $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install_$time" );
117     mkdir($client_fai_log_dir, 0755);
119     my @all_logs = split(/log_file:/, $all_logs); 
120     foreach my $log (@all_logs) {
121         if (length $log == 0) { next; };
122         my ($log_file, $log_string) = split(":", $log);
123         my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
125         open(my $LOG_FILE, ">$client_fai_log_file"); 
126         print $LOG_FILE &decode_base64($log_string);
127         close($LOG_FILE);
129     }
130     return;
134 sub LOGIN {
135     my ($msg, $msg_hash, $session_id) = @_;
136     my $header = @{$msg_hash->{'header'}}[0];
137     my $source = @{$msg_hash->{'source'}}[0];
138     my $login = @{$msg_hash->{$header}}[0];
140     my %add_hash = ( table=>$main::login_users_tn, 
141         primkey=> ['client', 'user'],
142         client=>$source,
143         user=>$login,
144         timestamp=>&get_time,
145         ); 
146     my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
147     if ($res != 0)  {
148         &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
149         return;
150     }
152     return;   
156 sub LOGOUT {
157     my ($msg, $msg_hash, $session_id) = @_;
158     my $header = @{$msg_hash->{'header'}}[0];
159     my $source = @{$msg_hash->{'source'}}[0];
160     my $login = @{$msg_hash->{$header}}[0];
161     
162     my $sql_statement = "DELETE FROM $main::login_users_tn WHERE (client='$source' AND user='$login')"; 
163     my $res =  $main::login_users_db->del_dbentry($sql_statement);
164     &main::daemon_log("$session_id INFO: delete user '$login' at client '$source' from login_user_db", 5); 
165     
166     return;
170 sub CURRENTLY_LOGGED_IN {
171     my ($msg, $msg_hash, $session_id) = @_;
172     my ($sql_statement, $db_res);
173     my $header = @{$msg_hash->{'header'}}[0];
174     my $source = @{$msg_hash->{'source'}}[0];
175     my $login = @{$msg_hash->{$header}}[0];
177     if(ref $login eq "HASH") { 
178         &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5); 
179         return;     
180     }
181     
182     # fetch all user currently assigned to the client at login_users_db
183     my %currently_logged_in_user = (); 
184     $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'"; 
185     $db_res = $main::login_users_db->select_dbentry($sql_statement);
186     while( my($hit_id, $hit) = each(%{$db_res}) ) {
187         $currently_logged_in_user{$hit->{'user'}} = 1;
188     }
189     &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7); 
191     # update all reported users in login_user_db
192     my @logged_in_user = split(/\s+/, $login);
193     &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7); 
194     foreach my $user (@logged_in_user) {
195         my %add_hash = ( table=>$main::login_users_tn, 
196                 primkey=> ['client', 'user'],
197                 client=>$source,
198                 user=>$user,
199                 timestamp=>&get_time,
200                 ); 
201         my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
202         if ($res != 0)  {
203             &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
204             return;
205         }
207         delete $currently_logged_in_user{$user};
208     }
210     # if there is still a user in %currently_logged_in_user 
211     # although he is not reported by client 
212     # then delete it from $login_user_db
213     foreach my $obsolete_user (keys(%currently_logged_in_user)) {
214         &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
215                 "in at client '$source' but still found at login_user_db", 3); 
216         my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'"; 
217         my $res =  $main::login_users_db->del_dbentry($sql_statement);
218         &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3); 
219     }
221     return;
225 sub GOTOACTIVATION {
226     my ($msg, $msg_hash, $session_id) = @_;
227     my $header = @{$msg_hash->{'header'}}[0];
228     my $source = @{$msg_hash->{'target'}}[0];
229     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
231     # test whether content is an empty hash or a string which is required
232     my $content = @{$msg_hash->{$header}}[0];
233     if(ref($content) eq "HASH") { $content = ""; }
235     # clean up header
236     $header =~ s/CLMSG_//g;
238     my $sql_statement = "UPDATE $main::job_queue_tn ".
239             "SET status='processing', progress='goto-activation' ".
240             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
241     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
242     my $res = $main::job_db->update_dbentry($sql_statement);
243     &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5); 
244     return; 
248 sub PROGRESS {
249     my ($msg, $msg_hash, $session_id) = @_;
250     my $header = @{$msg_hash->{'header'}}[0];
251     my $source = @{$msg_hash->{'target'}}[0];
252     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
254     # test whether content is an empty hash or a string which is required
255     my $content = @{$msg_hash->{$header}}[0];
256     if(ref($content) eq "HASH") { $content = ""; }
258     # clean up header
259     $header =~ s/CLMSG_//g;
261     my $sql_statement = "UPDATE $main::job_queue_tn ".
262         "SET progress='$content' ".
263         "WHERE status='processing' AND macaddress LIKE '$macaddress'";
264     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
265     my $res = $main::job_db->update_dbentry($sql_statement);
266     &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5); 
268     return;
272 sub FAIREBOOT {
273     my ($msg, $msg_hash, $session_id) = @_;
274     my $header = @{$msg_hash->{'header'}}[0];
275     my $source = @{$msg_hash->{'target'}}[0];
276     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
278     # test whether content is an empty hash or a string which is required
279         my $content = @{$msg_hash->{$header}}[0];
280     if(ref($content) eq "HASH") { $content = ""; }
282     # clean up header
283     $header =~ s/CLMSG_//g;
285     my $sql_statement = "UPDATE $main::job_queue_tn ".
286             "SET status='processing', result='$header "."$content' ".
287             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
288     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
289     my $res = $main::job_db->update_dbentry($sql_statement);
290     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
292     return; 
296 sub TASKSKIP {
297     my ($msg, $msg_hash, $session_id) = @_;
298     my $header = @{$msg_hash->{'header'}}[0];
299     my $source = @{$msg_hash->{'target'}}[0];
300     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
302     # test whether content is an empty hash or a string which is required
303         my $content = @{$msg_hash->{$header}}[0];
304     if(ref($content) eq "HASH") { $content = ""; }
306     # clean up header
307     $header =~ s/CLMSG_//g;
309     my $sql_statement = "UPDATE $main::job_queue_tn ".
310             "SET status='processing', result='$header "."$content' ".
311             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
312     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
313     my $res = $main::job_db->update_dbentry($sql_statement);
314     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
316     return; 
320 sub TASKBEGIN {
321     my ($msg, $msg_hash, $session_id) = @_;
322     my $header = @{$msg_hash->{'header'}}[0];
323     my $source = @{$msg_hash->{'target'}}[0];
324     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
326     # test whether content is an empty hash or a string which is required
327         my $content = @{$msg_hash->{$header}}[0];
328     if(ref($content) eq "HASH") { $content = ""; }
330     # clean up header
331     $header =~ s/CLMSG_//g;
333     # TASKBEGIN eq finish or faiend 
334     if (($content eq 'finish') 
335                         || ($content eq 'faiend')
336                         || ($content eq 'savelog')
337                         ) {
338         my $sql_statement = "UPDATE $main::job_queue_tn ".
339             "SET status='done', result='$header "."$content' ".
340             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
341         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
342         my $res = $main::job_db->update_dbentry($sql_statement);
343         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
344         
345         # set fai_state to localboot
346         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
348         # TASKBEGIN eq chboot
349         } elsif (($content eq 'chboot')
350                 || ($content eq 'test')
351                 || ($content eq 'confdir')
352                 ) {
353                 # just ignor this client message
354                 # do nothing
356         # other TASKBEGIN msgs
357     } else {
358                 # select processing jobs for host
359                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
360                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
361                 my $res = $main::job_db->select_dbentry($sql_statement);
363                 # there is exactly one job entry in queue for this host
364                 if (keys(%$res) == 1) {
365                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
366                         my $sql_statement = "UPDATE $main::job_queue_tn SET result='$header $content' WHERE status='processing' AND macaddress LIKE '$macaddress'";
367                         my $err = $main::job_db->update_dbentry($sql_statement);
368                         if (not defined  $err) {
369                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
370                         }
371                         
372                 # there is no entry or more than one enties
373                 } else {
374                         # in case of more than one running jobs in queue, delete all jobs
375                         if (keys(%$res) > 1) {
376                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
377                                                                 "delete entries", 7); 
379                                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
380                                 my ($err) = $main::job_db->del_dbentry($sql_statement);
381                                 if (not defined $err) {
382                                         &main::daemon_log("$session_id ERROR: can not delete multiple processing queue entries for host '$macaddress': ".Dumper($err), 1); 
383                                 }
384                         }
385                 
386                         # in case of no and more than one running jobs in queue, add one single job
387                         # resolve plain name for host $macaddress
388                         my $plain_name;
389                         my $ldap_handle = &main::get_ldap_handle($session_id);
390                         if( not defined $ldap_handle ) {
391                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
392                                 $plain_name = "none";
394                         # try to fetch a 'real name'
395                         } else {
396                                 my $mesg = $ldap_handle->search(
397                                                 base => $main::ldap_base,
398                                                 scope => 'sub',
399                                                 attrs => ['cn'],
400                                                 filter => "(macAddress=$macaddress)");
401                                 if($mesg->code) {
402                                         &main::daemon_log($mesg->error, 1);
403                                         $plain_name = "none";
404                                 } else {
405                                         my $entry= $mesg->entry(0);
406                                         $plain_name = $entry->get_value("cn");
407                                 }
408                         }
411                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
412                         my $func_dic = {table=>$main::job_queue_tn,
413                                         primkey=>['macaddress', 'headertag'],
414                                         timestamp=>&get_time,
415                                         status=>'processing',
416                                         result=>"$header $content",
417                                         progress=>'none',
418                                         headertag=>'trigger_action_reinstall',
419                                         targettag=>$source,
420                                         xmlmessage=>'none',
421                                         macaddress=>$macaddress,
422                                         plainname=>$plain_name,
423                         };
424                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
425                         if ($err != 0)  {
426                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
427                         }
429                 }
431 # -----------------------> Update hier
432 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
433 #  <header>CLMSG_TASKBEGIN</header>
434 # macaddress auslesen, Client im LDAP lokalisieren
435 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
436     }
438     return; 
442 sub TASKEND {
443     my ($msg, $msg_hash, $session_id) = @_;
444     my $header = @{$msg_hash->{'header'}}[0];
445     my $source = @{$msg_hash->{'target'}}[0];
446     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
448     # test whether content is an empty hash or a string which is required
449     my $content = @{$msg_hash->{$header}}[0];
450     if(ref($content) eq "HASH") { $content = ""; }
452     # clean up header
453     $header =~ s/CLMSG_//g;
455         if ($content eq "savelog 0") {
456                 &main::daemon_log("$session_id DEBUG: got savelog from host '$source' - jub done", 7);
457                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
458                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
459                 my $res = $main::job_db->del_dbentry($sql_statement);
461         } else {
463                         my $sql_statement = "UPDATE $main::job_queue_tn ".
464                                         "SET status='processing', result='$header "."$content' ".
465                                         "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
466                         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
467                         my $res = $main::job_db->update_dbentry($sql_statement);
468                         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
470         }
471 # -----------------------> Update hier
472 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
473 #  <header>CLMSG_TASKBEGIN</header>
474 # macaddress auslesen, Client im LDAP lokalisieren
475 # FAIstate auf "error" setzen
477     return; 
481 sub TASKERROR {
482     my ($msg, $msg_hash, $session_id) = @_;
483     my $header = @{$msg_hash->{'header'}}[0];
484     my $source = @{$msg_hash->{'target'}}[0];
485     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
487     # clean up header
488     $header =~ s/CLMSG_//g;
490     # test whether content is an empty hash or a string which is required
491     my $content = @{$msg_hash->{$header}}[0];
492     if(ref($content) eq "HASH") { $content = ""; } 
494         # set fai_state to localboot
495         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
496                 
497     my $sql_statement = "UPDATE $main::job_queue_tn ".
498             "SET status='processing', result='$header "."$content' ".
499             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
500     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
501     my $res = $main::job_db->update_dbentry($sql_statement);
502     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
504 # -----------------------> Update hier
505 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
506 #  <header>CLMSG_TASKBEGIN</header>
507 # macaddress auslesen, Client im LDAP lokalisieren
508 # FAIstate auf "error" setzen
510     return; 
514 sub HOOK {
515     my ($msg, $msg_hash, $session_id) = @_;
516     my $header = @{$msg_hash->{'header'}}[0];
517     my $source = @{$msg_hash->{'target'}}[0];
518     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
520     # clean up header
521     $header =~ s/CLMSG_//g;
523     # test whether content is an empty hash or a string which is required
524         my $content = @{$msg_hash->{$header}}[0];
525     if(not ref($content) eq "STRING") { $content = ""; }
527     my $sql_statement = "UPDATE $main::job_queue_tn ".
528             "SET status='processing', result='$header "."$content' ".
529             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
530     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
531     my $res = $main::job_db->update_dbentry($sql_statement);
532     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
534     return;
538 1;