Code

* gosa-si-server-nobus
[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') || ($content eq 'faiend')){
335         my $sql_statement = "UPDATE $main::job_queue_tn ".
336             "SET status='done', result='$header "."$content' ".
337             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
338         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
339         my $res = $main::job_db->update_dbentry($sql_statement);
340         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
341         
342         # set fai_state to localboot
343         &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
345         # other TASKBEGIN msgs
346     } else {
347                 # select processing jobs for host
348                 my $sql_statement = "SELECT * FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
349                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
350                 my $res = $main::job_db->select_dbentry($sql_statement);
352                 # there is exactly one job entry in queue for this host
353                 if (keys(%$res) == 1) {
354                         &main::daemon_log("$session_id DEBUG: there is already one processing job in queue for host '$macaddress', run an update for this entry", 7);
355                         my $sql_statement = "UPDATE $main::job_queue_tn SET result='$header $content' WHERE status='processing' AND macaddress LIKE '$macaddress'";
356                         my $err = $main::job_db->update_dbentry($sql_statement);
357                         if (not defined  $err) {
358                                 &main::daemon_log("$session_id ERROR: cannot update job_db entry: ".Dumper($err), 1);
359                         }
360                         
361                 # there is no entry or more than one enties
362                 } else {
363                         # in case of more than one running jobs in queue, delete all jobs
364                         if (keys(%$res) > 1) {
365                                 &main::daemon_log("$session_id DEBUG: there are more than one processing job in queue for host '$macaddress', ".
366                                                                 "delete entries", 7); 
368                                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'";
369                                 my ($err) = $main::job_db->del_dbentry($sql_statement);
370                                 if (not defined $err) {
371                                         &main::daemon_log("$session_id ERROR: can not delete multiple processing queue entries for host '$macaddress': ".Dumper($err), 1); 
372                                 }
373                         }
374                 
375                         # in case of no and more than one running jobs in queue, add one single job
376                         # resolve plain name for host $macaddress
377                         my $plain_name;
378                         my $ldap_handle = &main::get_ldap_handle($session_id);
379                         if( not defined $ldap_handle ) {
380                                 &main::daemon_log("$session_id ERROR: cannot connect to ldap", 1);
381                                 $plain_name = "none";
383                         # try to fetch a 'real name'
384                         } else {
385                                 my $mesg = $ldap_handle->search(
386                                                 base => $main::ldap_base,
387                                                 scope => 'sub',
388                                                 attrs => ['cn'],
389                                                 filter => "(macAddress=$macaddress)");
390                                 if($mesg->code) {
391                                         &main::daemon_log($mesg->error, 1);
392                                         $plain_name = "none";
393                                 } else {
394                                         my $entry= $mesg->entry(0);
395                                         $plain_name = $entry->get_value("cn");
396                                 }
397                         }
400                         &main::daemon_log("$session_id DEBUG: add job to queue for host '$macaddress'", 7); 
401                         my $func_dic = {table=>$main::job_queue_tn,
402                                         primkey=>[],
403                                         timestamp=>&get_time,
404                                         status=>'processing',
405                                         result=>"$header $content",
406                                         progress=>'none',
407                                         headertag=>'trigger_action_reinstall',
408                                         targettag=>$source,
409                                         xmlmessage=>'none',
410                                         macaddress=>$macaddress,
411                                         plainname=>$plain_name,
412                         };
413                         my ($err, $error_str) = $main::job_db->add_dbentry($func_dic);
414                         if ($err != 0)  {
415                                         &main::daemon_log("$session_id ERROR: cannot add entry to job_db: $error_str", 1);
416                         }
418                 }
420 # -----------------------> Update hier
421 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
422 #  <header>CLMSG_TASKBEGIN</header>
423 # macaddress auslesen, Client im LDAP lokalisieren
424 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
425     }
427     return; 
431 sub TASKEND {
432     my ($msg, $msg_hash, $session_id) = @_;
433     my $header = @{$msg_hash->{'header'}}[0];
434     my $source = @{$msg_hash->{'target'}}[0];
435     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
437     # test whether content is an empty hash or a string which is required
438     my $content = @{$msg_hash->{$header}}[0];
439     if(ref($content) eq "HASH") { $content = ""; }
441     # clean up header
442     $header =~ s/CLMSG_//g;
444         if ($content eq "savelog 0") {
445                 &main::daemon_log("$session_id DEBUG: got savelog from host '$source' - jub done", 7);
446                 my $sql_statement = "DELETE FROM $main::job_queue_tn WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
447                 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
448                 my $res = $main::job_db->del_dbentry($sql_statement);
450         } else {
452                         my $sql_statement = "UPDATE $main::job_queue_tn ".
453                                         "SET status='processing', result='$header "."$content' ".
454                                         "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
455                         &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
456                         my $res = $main::job_db->update_dbentry($sql_statement);
457                         &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
459         }
460 # -----------------------> Update hier
461 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
462 #  <header>CLMSG_TASKBEGIN</header>
463 # macaddress auslesen, Client im LDAP lokalisieren
464 # FAIstate auf "error" setzen
466     return; 
470 sub TASKERROR {
471     my ($msg, $msg_hash, $session_id) = @_;
472     my $header = @{$msg_hash->{'header'}}[0];
473     my $source = @{$msg_hash->{'target'}}[0];
474     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
476     # clean up header
477     $header =~ s/CLMSG_//g;
479     # test whether content is an empty hash or a string which is required
480     my $content = @{$msg_hash->{$header}}[0];
481     if(ref($content) eq "HASH") { $content = ""; } 
483         # set fai_state to localboot
484         &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
485                 
486     my $sql_statement = "UPDATE $main::job_queue_tn ".
487             "SET status='processing', result='$header "."$content' ".
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); 
493 # -----------------------> Update hier
494 #  <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
495 #  <header>CLMSG_TASKBEGIN</header>
496 # macaddress auslesen, Client im LDAP lokalisieren
497 # FAIstate auf "error" setzen
499     return; 
503 sub HOOK {
504     my ($msg, $msg_hash, $session_id) = @_;
505     my $header = @{$msg_hash->{'header'}}[0];
506     my $source = @{$msg_hash->{'target'}}[0];
507     my $macaddress = @{$msg_hash->{'macaddress'}}[0];
509     # clean up header
510     $header =~ s/CLMSG_//g;
512     # test whether content is an empty hash or a string which is required
513         my $content = @{$msg_hash->{$header}}[0];
514     if(ref($content) eq "HASH") { $content = ""; }
516     my $sql_statement = "UPDATE $main::job_queue_tn ".
517             "SET status='processing', result='$header "."$content' ".
518             "WHERE status='processing' AND macaddress LIKE '$macaddress'"; 
519     &main::daemon_log("$session_id DEBUG: $sql_statement", 7);         
520     my $res = $main::job_db->update_dbentry($sql_statement);
521     &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5); 
523     return;
527 1;