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 #########
226 # testing
227 my $content = @{$msg_hash->{$header}}[0];
228 if(ref($content) eq "HASH") { $content = ""; }
229 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
230 #if( $@ ) { $content = "$content"; }
231 # testing
232 ########
234 # clean up header
235 $header =~ s/CLMSG_//g;
237 my $sql_statement = "UPDATE $main::job_queue_tn ".
238 "SET status='processing', result='$header"."$content' ".
239 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
240 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
241 my $res = $main::job_db->update_dbentry($sql_statement);
242 &main::daemon_log("$session_id INFO: $header at '$macaddress'", 5);
243 return;
244 }
247 sub PROGRESS {
248 my ($msg, $msg_hash, $session_id) = @_;
249 my $header = @{$msg_hash->{'header'}}[0];
250 my $source = @{$msg_hash->{'target'}}[0];
251 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
253 # test whether content is an empty hash or a string which is required
254 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
255 #########
256 # testing
257 my $content = @{$msg_hash->{$header}}[0];
258 if(ref($content) eq "HASH") { $content = ""; }
259 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
260 #if( $@ ) { $content = "$content"; }
261 # testing
262 ########
264 # clean up header
265 $header =~ s/CLMSG_//g;
267 my $sql_statement = "UPDATE $main::job_queue_tn ".
268 "SET progress='$content' ".
269 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
270 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
271 my $res = $main::job_db->update_dbentry($sql_statement);
272 &main::daemon_log("$session_id INFO: $header at '$macaddress' - $content%", 5);
274 return;
275 }
278 sub FAIREBOOT {
279 my ($msg, $msg_hash, $session_id) = @_;
280 my $header = @{$msg_hash->{'header'}}[0];
281 my $source = @{$msg_hash->{'target'}}[0];
282 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
284 # test whether content is an empty hash or a string which is required
285 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
286 #########
287 # testing
288 my $content = @{$msg_hash->{$header}}[0];
289 if(ref($content) eq "HASH") { $content = ""; }
290 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
291 #if( $@ ) { $content = "$content"; }
292 # testing
293 #########
295 # clean up header
296 $header =~ s/CLMSG_//g;
298 my $sql_statement = "UPDATE $main::job_queue_tn ".
299 "SET status='processing', result='$header "."$content' ".
300 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
301 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
302 my $res = $main::job_db->update_dbentry($sql_statement);
303 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
305 return;
306 }
309 sub TASKSKIP {
310 my ($msg, $msg_hash, $session_id) = @_;
311 my $header = @{$msg_hash->{'header'}}[0];
312 my $source = @{$msg_hash->{'target'}}[0];
313 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
315 # test whether content is an empty hash or a string which is required
316 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
317 #########
318 # testing
319 my $content = @{$msg_hash->{$header}}[0];
320 if(ref($content) eq "HASH") { $content = ""; }
321 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
322 #if( $@ ) { $content = "$content"; }
323 # testing
324 #########
326 # clean up header
327 $header =~ s/CLMSG_//g;
329 my $sql_statement = "UPDATE $main::job_queue_tn ".
330 "SET status='processing', result='$header "."$content' ".
331 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
332 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
333 my $res = $main::job_db->update_dbentry($sql_statement);
334 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
336 return;
337 }
340 sub TASKBEGIN {
341 my ($msg, $msg_hash, $session_id) = @_;
342 my $header = @{$msg_hash->{'header'}}[0];
343 my $source = @{$msg_hash->{'target'}}[0];
344 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
345 my $content = @{$msg_hash->{$header}}[0];
347 # test whether content is an empty hash or a string which is required
348 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
349 #########
350 # testing
351 my $content = @{$msg_hash->{$header}}[0];
352 if(ref($content) eq "HASH") { $content = ""; }
353 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
354 #if( $@ ) { $content = "$content"; }
355 # testing
356 #########
358 # clean up header
359 $header =~ s/CLMSG_//g;
361 # check if installation finished
362 if (($content eq 'finish') || ($content eq 'faiend')){
363 my $sql_statement = "UPDATE $main::job_queue_tn ".
364 "SET status='done', result='$header "."$content' ".
365 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
366 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
367 my $res = $main::job_db->update_dbentry($sql_statement);
368 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
370 # set fai_state to localboot
371 &main::change_fai_state('localboot', \@{$msg_hash->{'macaddress'}}, $session_id);
373 } else {
374 my $sql_statement = "UPDATE $main::job_queue_tn ".
375 "SET status='processing', result='$header "."$content' ".
376 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
377 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
378 my $res = $main::job_db->update_dbentry($sql_statement);
379 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
382 # -----------------------> Update hier
383 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
384 # <header>CLMSG_TASKBEGIN</header>
385 # macaddress auslesen, Client im LDAP lokalisieren
386 # FAIstate auf "localboot" setzen, wenn FAIstate "install" oder "softupdate" war
387 }
389 return;
390 }
393 sub TASKEND {
394 my ($msg, $msg_hash, $session_id) = @_;
395 my $header = @{$msg_hash->{'header'}}[0];
396 my $source = @{$msg_hash->{'target'}}[0];
397 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
399 # test whether content is an empty hash or a string which is required
400 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
401 #########
402 # testing
403 my $content = @{$msg_hash->{$header}}[0];
404 if(ref($content) eq "HASH") { $content = ""; }
405 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
406 #if( $@ ) { $content = "$content"; }
407 # testing
408 #########
410 # clean up header
411 $header =~ s/CLMSG_//g;
413 my $sql_statement = "UPDATE $main::job_queue_tn ".
414 "SET status='processing', result='$header "."$content' ".
415 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
416 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
417 my $res = $main::job_db->update_dbentry($sql_statement);
418 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
420 # -----------------------> Update hier
421 # <CLMSG_TASKBEGIN>finish</CLMSG_TASKBEGIN>
422 # <header>CLMSG_TASKBEGIN</header>
423 # macaddress auslesen, Client im LDAP lokalisieren
424 # FAIstate auf "error" setzen
426 return;
427 }
430 sub TASKERROR {
431 my ($msg, $msg_hash, $session_id) = @_;
432 my $header = @{$msg_hash->{'header'}}[0];
433 my $source = @{$msg_hash->{'target'}}[0];
434 my $macaddress = @{$msg_hash->{'macaddress'}}[0];
436 # clean up header
437 $header =~ s/CLMSG_//g;
439 # test whether content is an empty hash or a string which is required
440 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
441 #########
442 # testing
443 my $content = @{$msg_hash->{$header}}[0];
444 if(ref($content) eq "HASH") { $content = ""; }
445 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
446 #if( $@ ) { $content = "$content"; }
447 # testing
448 #########
450 # set fai_state to localboot
451 &main::change_fai_state('error', \@{$msg_hash->{'macaddress'}}, $session_id);
453 my $sql_statement = "UPDATE $main::job_queue_tn ".
454 "SET status='processing', result='$header "."$content' ".
455 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
456 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
457 my $res = $main::job_db->update_dbentry($sql_statement);
458 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
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;
467 }
470 sub HOOK {
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 # TODO eval ändern auf if(ref($content) eq "HASH") dann ... else, dann...
481 #########
482 # testing
483 my $content = @{$msg_hash->{$header}}[0];
484 if(ref($content) eq "HASH") { $content = ""; }
485 #eval{ if( 0 == keys(%$content) ) { $content = ""; } };
486 #if( $@ ) { $content = "$content"; }
487 # testing
488 #########
490 my $sql_statement = "UPDATE $main::job_queue_tn ".
491 "SET status='processing', result='$header "."$content' ".
492 "WHERE status='processing' AND macaddress LIKE '$macaddress'";
493 &main::daemon_log("$session_id DEBUG: $sql_statement", 7);
494 my $res = $main::job_db->update_dbentry($sql_statement);
495 &main::daemon_log("$session_id INFO: $header at '$macaddress' - '$content'", 5);
497 return;
498 }
501 1;