Code

Migrated to get_cfg_value
[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->{'source'}}[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', modified='1' ".
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->{'source'}}[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', modified='1' ".
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->{'source'}}[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', modified='1' ".
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->{'source'}}[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', modified='1' ".
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->{'source'}}[0];
324     my $target = @{$msg_hash->{'target'}}[0];
325     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
327     # test whether content is an empty hash or a string which is required
328         my $content = @{$msg_hash->{$header}}[0];
329     if(ref($content) eq "HASH") { $content = ""; }
331     # clean up header
332     $header =~ s/CLMSG_//g;
334     # TASKBEGIN eq finish or faiend 
335     if (($content eq 'finish') 
336                         || ($content eq 'faiend')
337                         || ($content eq 'savelog')
338                         ) {
339         my $sql_statement = "UPDATE $main::job_queue_tn ".
340             "SET status='done', result='$header "."$content', modified='1' ".
341             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
342         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
343         my $res = $main::job_db->update_dbentry($sql_statement);
344         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
345         
346         # set fai_state to localboot
347         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
349         # TASKBEGIN eq chboot
350         } elsif (($content eq 'chboot')
351                 || ($content eq 'test')
352                 || ($content eq 'confdir')
353                 ) {
354                 # just ignor this client message
355                 # do nothing
357         # other TASKBEGIN msgs
358     } else {
359                 # select processing jobs for host
360                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
361                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
362                 my $res = $main::job_db->select_dbentry($sql_statement);
364                 # there is exactly one job entry in queue for this host
365                 if (keys(%$res) == 1) {
366                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
367                         my $sql_statement = "UPDATE $main::job_queue_tn ".
368                 "SET result='$header $content', modified='1' ".
369                 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
370                         my $err = $main::job_db->update_dbentry($sql_statement);
371                         if (not defined  $err) {
372                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
373                         }
374                         
375                 # there is no entry or more than one enties
376                 } else {
377                         # in case of more than one running jobs in queue, delete all jobs
378                         if (keys(%$res) > 1) {
379                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
380                                                                 "delete entries", 7); 
382                 # set job to status 'done', job will be deleted automatically
383                 my $sql_statement = "UPDATE $main::job_queue_tn ".
384                     "SET status='done', modified='1'".
385                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
386                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
387                 my $res = $main::job_db->update_dbentry( $sql_statement );
389                         }
390                 
391                         # in case of no and more than one running jobs in queue, add one single job
392                         # resolve plain name for host $macaddress
393                         my $plain_name;
394                         my $ldap_handle = &main::get_ldap_handle($session_id);
395                         if( not defined $ldap_handle ) {
396                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
397                                 $plain_name = "none";
399                         # try to fetch a 'real name'
400                         } else {
401                                 my $mesg = $ldap_handle->search(
402                                                 base => $main::ldap_base,
403                                                 scope => 'sub',
404                                                 attrs => ['cn'],
405                                                 filter => "(macAddress=$macaddress)");
406                                 if($mesg->code) {
407                                         &main::daemon_log($mesg->error, 1);
408                                         $plain_name = "none";
409                                 } else {
410                                         my $entry= $mesg->entry(0);
411                                         $plain_name = $entry->get_value("cn");
412                                 }
413                         }
416                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
417                         my $func_dic = {table=>$main::job_queue_tn,
418                                         primkey=>['macaddress', 'headertag'],
419                                         timestamp=>&get_time,
420                                         status=>'processing',
421                                         result=>"$header $content",
422                                         progress=>'none',
423                                         headertag=>'trigger_action_reinstall',
424                                         targettag=>$target,
425                                         xmlmessage=>'none',
426                                         macaddress=>$macaddress,
427                                         plainname=>$plain_name,
428                     modified=>'1',
429                     siserver=>$source,
430                         };
431                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
432                         if ($err != 0)  {
433                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
434                         }
436                 }
438 # -----------------------> Update hier
439 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
440 #  <header>CLMSG_TASKBEGIN</header>
441 # macaddress auslesen, Client im LDAP lokalisieren
442 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
443     }
445     return; 
449 sub TASKEND {
450     my ($msg, $msg_hash, $session_id) = @_;
451     my $header = @{$msg_hash->{'header'}}[0];
452     my $target = @{$msg_hash->{'target'}}[0];
453     my $source = @{$msg_hash->{'source'}}[0];
454     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
456     # test whether content is an empty hash or a string which is required
457     my $content = @{$msg_hash->{$header}}[0];
458     if(ref($content) eq "HASH") { $content = ""; }
460     # clean up header
461     $header =~ s/CLMSG_//g;
463         if ($content eq "savelog 0") {
464                 &main::daemon_log("$session_id DEBUG: got savelog from host '$target' - job done", 7);
465         
466         # set job to status 'done', job will be deleted automatically
467         my $sql_statement = "UPDATE $main::job_queue_tn ".
468                                         "SET status='done', modified='1'".
469                     "WHERE status='processing' AND macaddress LIKE '$macaddress'";
470         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
471         my $res = $main::job_db->update_dbentry( $sql_statement );
473         } else {
474         my $sql_statement = "UPDATE $main::job_queue_tn ".
475             "SET status='processing', result='$header "."$content', modified='1' ".
476             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
477         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
478         my $res = $main::job_db->update_dbentry($sql_statement);
479         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
480         }
482     return; 
486 sub TASKERROR {
487     my ($msg, $msg_hash, $session_id) = @_;
488     my $header = @{$msg_hash->{'header'}}[0];
489     my $source = @{$msg_hash->{'source'}}[0];
490     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
492     # clean up header
493     $header =~ s/CLMSG_//g;
495     # test whether content is an empty hash or a string which is required
496     my $content = @{$msg_hash->{$header}}[0];
497     if(ref($content) eq "HASH") { $content = ""; } 
499         # set fai_state to localboot
500         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
501                 
502     my $sql_statement = "UPDATE $main::job_queue_tn ".
503             "SET status='processing', result='$header "."$content', modified='1' ".
504             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
505     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
506     my $res = $main::job_db->update_dbentry($sql_statement);
507     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
509 # -----------------------> Update hier
510 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
511 #  <header>CLMSG_TASKBEGIN</header>
512 # macaddress auslesen, Client im LDAP lokalisieren
513 # FAIstate auf "error" setzen
515     return; 
519 sub HOOK {
520     my ($msg, $msg_hash, $session_id) = @_;
521     my $header = @{$msg_hash->{'header'}}[0];
522     my $source = @{$msg_hash->{'source'}}[0];
523     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
525     # clean up header
526     $header =~ s/CLMSG_//g;
528     # test whether content is an empty hash or a string which is required
529         my $content = @{$msg_hash->{$header}}[0];
530     if(not ref($content) eq "STRING") { $content = ""; }
532     my $sql_statement = "UPDATE $main::job_queue_tn ".
533             "SET status='processing', result='$header "."$content', modified='1' ".
534             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
535     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
536     my $res = $main::job_db->update_dbentry($sql_statement);
537     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
539     return;
543 1;