1 package clMessages;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5 "PROGRESS",
6 "FAIREBOOT",
7 "TASKSKIP",
8 "TASKBEGIN",
9 "TASKEND",
10 "TASKERROR",
11 "HOOK",
12 "GOTOACTIVATION",
13 "LOGIN",
14 "LOGOUT",
15 "CURRENTLY_LOGGED_IN",
16 "save_fai_log",
17 );
18 @EXPORT = @events;
20 use strict;
21 use warnings;
22 use Data::Dumper;
23 use GOSA::GosaSupportDaemon;
24 use MIME::Base64;
27 BEGIN {}
29 END {}
31 ### Start ######################################################################
33 my $ldap_uri;
34 my $ldap_base;
35 my $ldap_admin_dn;
36 my $ldap_admin_password;
38 my %cfg_defaults = (
39 "server" => {
40 "ldap-uri" => [\$ldap_uri, ""],
41 "ldap-base" => [\$ldap_base, ""],
42 "ldap-admin-dn" => [\$ldap_admin_dn, ""],
43 "ldap-admin-password" => [\$ldap_admin_password, ""],
44 },
45 );
46 &read_configfile($main::cfg_file, %cfg_defaults);
49 sub get_events {
50 return \@events;
51 }
54 sub read_configfile {
55 my ($cfg_file, %cfg_defaults) = @_;
56 my $cfg;
58 if( defined( $cfg_file) && ( length($cfg_file) > 0 )) {
59 if( -r $cfg_file ) {
60 $cfg = Config::IniFiles->new( -file => $cfg_file );
61 } else {
62 &main::daemon_log("ERROR: clMessages.pm couldn't read config file!", 1);
63 }
64 } else {
65 $cfg = Config::IniFiles->new() ;
66 }
67 foreach my $section (keys %cfg_defaults) {
68 foreach my $param (keys %{$cfg_defaults{ $section }}) {
69 my $pinfo = $cfg_defaults{ $section }{ $param };
70 ${@$pinfo[0]} = $cfg->val( $section, $param, @$pinfo[1] );
71 }
72 }
73 }
76 sub save_fai_log {
77 my ($msg, $msg_hash, $session_id) = @_;
78 my $header = @{$msg_hash->{'header'}}[0];
79 my $source = @{$msg_hash->{'source'}}[0];
80 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
81 my $all_logs = @{$msg_hash->{$header}}[0];
83 # if there is nothing to log
84 if( ref($all_logs) eq "HASH" ) { return; }
86 my $client_fai_log_dir = $main::client_fai_log_dir;
87 if (not -d $client_fai_log_dir) {
88 mkdir($client_fai_log_dir, 0755)
89 }
91 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, $macaddress );
92 if (not -d $client_fai_log_dir) {
93 mkdir($client_fai_log_dir, 0755)
94 }
96 my $time = &get_time;
97 $time = substr($time, 0, 8)."_".substr($time, 8, 6);
98 $client_fai_log_dir = File::Spec->catfile( $client_fai_log_dir, "install-$time" );
99 mkdir($client_fai_log_dir, 0755);
101 my @all_logs = split(/log_file:/, $all_logs);
102 foreach my $log (@all_logs) {
103 if (length $log == 0) { next; };
104 my ($log_file, $log_string) = split(":", $log);
105 my $client_fai_log_file = File::Spec->catfile( $client_fai_log_dir, $log_file);
107 open(my $LOG_FILE, ">$client_fai_log_file");
108 print $LOG_FILE &decode_base64($log_string);
109 close($LOG_FILE);
111 }
112 return;
113 }
116 sub LOGIN {
117 my ($msg, $msg_hash, $session_id) = @_;
118 my $header = @{$msg_hash->{'header'}}[0];
119 my $source = @{$msg_hash->{'source'}}[0];
120 my $login = @{$msg_hash->{$header}}[0];
122 my %add_hash = ( table=>$main::login_users_tn,
123 primkey=> ['client', 'user'],
124 client=>$source,
125 user=>$login,
126 timestamp=>&get_time,
127 );
128 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
129 if ($res != 0) {
130 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
131 return;
132 }
134 return;
135 }
137 # TODO umstellen wie bei LOGIN
138 sub LOGOUT {
139 my ($msg, $msg_hash, $session_id) = @_;
140 my $header = @{$msg_hash->{'header'}}[0];
141 my $source = @{$msg_hash->{'source'}}[0];
142 my $login = @{$msg_hash->{$header}}[0];
144 my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$source'";
145 my $res = $main::known_clients_db->select_dbentry($sql_statement);
146 if( 1 != keys(%$res) ) {
147 &main::daemon_log("DEBUG: clMessages.pm: LOGOUT: no or more hits found in known_clients_db for host '$source'");
148 return;
149 }
151 my $act_login = $res->{'1'}->{'login'};
152 $act_login =~ s/$login,?//gi;
154 if( $act_login eq "" ){ $act_login = "nobody"; }
156 $sql_statement = "UPDATE known_clients SET login='$act_login' WHERE hostname='$source'";
157 $res = $main::known_clients_db->update_dbentry($sql_statement);
159 return;
160 }
163 sub CURRENTLY_LOGGED_IN {
164 my ($msg, $msg_hash, $session_id) = @_;
165 my ($sql_statement, $db_res);
166 my $header = @{$msg_hash->{'header'}}[0];
167 my $source = @{$msg_hash->{'source'}}[0];
168 my $login = @{$msg_hash->{$header}}[0];
170 if(ref $login eq "HASH") {
171 &main::daemon_log("$session_id INFO: no logged in users reported from host '$source'", 5);
172 return;
173 }
175 # fetch all user currently assigned to the client at login_users_db
176 my %currently_logged_in_user = ();
177 $sql_statement = "SELECT * FROM $main::login_users_tn WHERE client='$source'";
178 $db_res = $main::login_users_db->select_dbentry($sql_statement);
179 while( my($hit_id, $hit) = each(%{$db_res}) ) {
180 $currently_logged_in_user{$hit->{'user'}} = 1;
181 }
182 &main::daemon_log("$session_id DEBUG: logged in users from login_user_db: ".join(", ", keys(%currently_logged_in_user)), 7);
184 # update all reported users in login_user_db
185 my @logged_in_user = split(/\s+/, $login);
186 &main::daemon_log("$session_id DEBUG: logged in users reported from client: ".join(", ", @logged_in_user), 7);
187 foreach my $user (@logged_in_user) {
188 my %add_hash = ( table=>$main::login_users_tn,
189 primkey=> ['client', 'user'],
190 client=>$source,
191 user=>$user,
192 timestamp=>&get_time,
193 );
194 my ($res, $error_str) = $main::login_users_db->add_dbentry( \%add_hash );
195 if ($res != 0) {
196 &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $error_str");
197 return;
198 }
200 delete $currently_logged_in_user{$user};
201 }
203 # if there is still a user in %currently_logged_in_user
204 # although he is not reported by client
205 # then delete it from $login_user_db
206 foreach my $obsolete_user (keys(%currently_logged_in_user)) {
207 &main::daemon_log("$session_id WARNING: user '$obsolete_user' is currently not logged ".
208 "in at client '$source' but still found at login_user_db", 3);
209 my $sql_statement = "DELETE FROM $main::login_users_tn WHERE client='$source' AND user='$obsolete_user'";
210 my $res = $main::login_users_db->del_dbentry($sql_statement);
211 &main::daemon_log("$session_id WARNING: delete user '$obsolete_user' at client '$source' from login_user_db", 3);
212 }
214 return;
215 }
218 sub GOTOACTIVATION {
219 my ($msg, $msg_hash, $session_id) = @_;
220 my $header = @{$msg_hash->{'header'}}[0];
221 my $source = @{$msg_hash->{'target'}}[0];
222 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
224 # test whether content is an empty hash or a string which is required
225 my $content = @{$msg_hash->{$header}}[0];
226 if(ref($content) eq "HASH") { $content = ""; }
228 # clean up header
229 $header =~ s/CLMSG_//g;
231 my $sql_statement = "UPDATE $main::job_queue_tn ".
232 "SET status='processing', progress='goto-activation' ".
233 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
234 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
235 my $res = $main::job_db->update_dbentry($sql_statement);
236 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
237 return;
238 }
241 sub PROGRESS {
242 my ($msg, $msg_hash, $session_id) = @_;
243 my $header = @{$msg_hash->{'header'}}[0];
244 my $source = @{$msg_hash->{'target'}}[0];
245 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
247 # test whether content is an empty hash or a string which is required
248 my $content = @{$msg_hash->{$header}}[0];
249 if(ref($content) eq "HASH") { $content = ""; }
251 # clean up header
252 $header =~ s/CLMSG_//g;
254 my $sql_statement = "UPDATE $main::job_queue_tn ".
255 "SET progress='$content' ".
256 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
257 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
258 my $res = $main::job_db->update_dbentry($sql_statement);
259 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
261 return;
262 }
265 sub FAIREBOOT {
266 my ($msg, $msg_hash, $session_id) = @_;
267 my $header = @{$msg_hash->{'header'}}[0];
268 my $source = @{$msg_hash->{'target'}}[0];
269 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
271 # test whether content is an empty hash or a string which is required
272 my $content = @{$msg_hash->{$header}}[0];
273 if(ref($content) eq "HASH") { $content = ""; }
275 # clean up header
276 $header =~ s/CLMSG_//g;
278 my $sql_statement = "UPDATE $main::job_queue_tn ".
279 "SET status='processing', result='$header "."$content' ".
280 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
281 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
282 my $res = $main::job_db->update_dbentry($sql_statement);
283 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
285 return;
286 }
289 sub TASKSKIP {
290 my ($msg, $msg_hash, $session_id) = @_;
291 my $header = @{$msg_hash->{'header'}}[0];
292 my $source = @{$msg_hash->{'target'}}[0];
293 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
295 # test whether content is an empty hash or a string which is required
296 my $content = @{$msg_hash->{$header}}[0];
297 if(ref($content) eq "HASH") { $content = ""; }
299 # clean up header
300 $header =~ s/CLMSG_//g;
302 my $sql_statement = "UPDATE $main::job_queue_tn ".
303 "SET status='processing', result='$header "."$content' ".
304 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
305 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
306 my $res = $main::job_db->update_dbentry($sql_statement);
307 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
309 return;
310 }
313 sub TASKBEGIN {
314 my ($msg, $msg_hash, $session_id) = @_;
315 my $header = @{$msg_hash->{'header'}}[0];
316 my $source = @{$msg_hash->{'target'}}[0];
317 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
319 # test whether content is an empty hash or a string which is required
320 my $content = @{$msg_hash->{$header}}[0];
321 if(ref($content) eq "HASH") { $content = ""; }
323 # clean up header
324 $header =~ s/CLMSG_//g;
326 # check if installation finished
327 if (($content eq 'finish') || ($content eq 'faiend')){
328 my $sql_statement = "UPDATE $main::job_queue_tn ".
329 "SET status='done', result='$header "."$content' ".
330 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
331 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
332 my $res = $main::job_db->update_dbentry($sql_statement);
333 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
334 #
335 # my $add_hash = { table=>$main::job_queue_tn,
336 # primkey=> ['id'],
337 # timestamp=>&get_time,
338 # status=>"'processing'",
339 # result=>"'$header $content'",
340 # progress=>"'none'",
341 # headertag=>"'trigger_action_reinstall'",
342 # targettag=>"'none'",
343 # xmlmessage=>"'none'",
344 # macaddress=>"'$macaddress'",
345 # };
346 # my ($res, $error_str) = $main::job_db->add_dbentry( $add_hash );
347 # if ($res != 0) {
348 # &main::daemon_log("$session_id ERROR: $res - can not add entry to $main::job_queue_tn: $error_str");
349 # } else {
350 # &main::daemon_log("$session_id INFO: '$header' at '$macaddress' - '$content'", 5);
351 # }
352 #
353 # set fai_state to localboot
354 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
356 } else {
357 my $sql_statement = "UPDATE $main::job_queue_tn ".
358 "SET status='processing', result='$header "."$content' ".
359 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
360 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
361 my $res = $main::job_db->update_dbentry($sql_statement);
362 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
364 #
365 # my $add_hash = { table=>$main::job_queue_tn,
366 # primkey=> ['id'],
367 # timestamp=>&get_time,
368 # status=>"'processing'",
369 # result=>"'$header $content'",
370 # progress=>"'none'",
371 # headertag=>"'trigger_action_reinstall'",
372 # targettag=>"'none'",
373 # xmlmessage=>"'none'",
374 # macaddress=>"'$macaddress'",
375 # };
376 # my ($res, $error_str) = $main::job_db->add_dbentry( $add_hash );
377 # if ($res != 0) {
378 # &main::daemon_log("$session_id ERROR: $res - can not add entry to $main::job_queue_tn: $error_str");
379 # } else {
380 # &main::daemon_log("$session_id INFO: '$header' at '$macaddress' - '$content'", 5);
381 # }
382 #
383 # -----------------------> Update hier
384 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
385 # <header>CLMSG_TASKBEGIN</header>
386 # macaddress auslesen, Client im LDAP lokalisieren
387 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
388 }
390 return;
391 }
394 sub TASKEND {
395 my ($msg, $msg_hash, $session_id) = @_;
396 my $header = @{$msg_hash->{'header'}}[0];
397 my $source = @{$msg_hash->{'target'}}[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 status='processing', result='$header "."$content' ".
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' - '$content'", 5);
414 # -----------------------> Update hier
415 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
416 # <header>CLMSG_TASKBEGIN</header>
417 # macaddress auslesen, Client im LDAP lokalisieren
418 # FAIstate auf "error" setzen
420 return;
421 }
424 sub TASKERROR {
425 my ($msg, $msg_hash, $session_id) = @_;
426 my $header = @{$msg_hash->{'header'}}[0];
427 my $source = @{$msg_hash->{'target'}}[0];
428 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
430 # clean up header
431 $header =~ s/CLMSG_//g;
433 # test whether content is an empty hash or a string which is required
434 my $content = @{$msg_hash->{$header}}[0];
435 if(ref($content) eq "HASH") { $content = ""; }
437 # set fai_state to localboot
438 &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
440 my $sql_statement = "UPDATE $main::job_queue_tn ".
441 "SET status='processing', result='$header "."$content' ".
442 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
443 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
444 my $res = $main::job_db->update_dbentry($sql_statement);
445 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
447 # -----------------------> Update hier
448 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
449 # <header>CLMSG_TASKBEGIN</header>
450 # macaddress auslesen, Client im LDAP lokalisieren
451 # FAIstate auf "error" setzen
453 return;
454 }
457 sub HOOK {
458 my ($msg, $msg_hash, $session_id) = @_;
459 my $header = @{$msg_hash->{'header'}}[0];
460 my $source = @{$msg_hash->{'target'}}[0];
461 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
463 # clean up header
464 $header =~ s/CLMSG_//g;
466 # test whether content is an empty hash or a string which is required
467 my $content = @{$msg_hash->{$header}}[0];
468 if(ref($content) eq "HASH") { $content = ""; }
470 my $sql_statement = "UPDATE $main::job_queue_tn ".
471 "SET status='processing', result='$header "."$content' ".
472 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
473 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
474 my $res = $main::job_db->update_dbentry($sql_statement);
475 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
477 return;
478 }
481 1;