1 package siTriggered;
2 use Exporter;
3 @ISA = qw(Exporter);
4 my @events = (
5 "got_ping",
6 "detected_hardware",
7 "trigger_wake",
8 "reload_ldap_config",
9 "get_terminal_server",
10 );
11 @EXPORT = @events;
13 use strict;
14 use warnings;
15 use Data::Dumper;
16 use GOSA::GosaSupportDaemon;
17 use Socket;
21 BEGIN {}
23 END {}
25 ### Start ######################################################################
27 my $ldap_uri;
28 my $ldap_base;
29 my $ldap_admin_dn;
30 my $ldap_admin_password;
31 my $mesg;
33 my %cfg_defaults = (
34 "server" => {
35 "ldap-uri" => [\$ldap_uri, ""],
36 "ldap-base" => [\$ldap_base, ""],
37 "ldap-admin-dn" => [\$ldap_admin_dn, ""],
38 "ldap-admin-password" => [\$ldap_admin_password, ""],
39 },
40 );
41 &GOSA::GosaSupportDaemon::read_configfile($main::cfg_file, %cfg_defaults);
44 sub get_terminal_server
45 {
46 my ($msg, $msg_hash, $session_id) = @_ ;
47 my $source = @{$msg_hash->{source}}[0];
48 my @out_msg_l;
50 # Send get_load message to all si-clients at terminal server specified in LDAP
51 my $ldap_handle = &main::get_ldap_handle();
52 if (defined $ldap_handle)
53 {
54 my $ldap_mesg = $ldap_handle->search(
55 base => $ldap_base,
56 scope => 'sub',
57 attrs => ['macAddress', 'cn', 'ipHostNumber'],
58 filter => "objectClass=goTerminalServer",
59 );
60 if ($ldap_mesg->count)
61 {
62 # Parse all LDAP results to a sql compliant where statement
63 my @entries = $ldap_mesg->entries;
64 @entries = map ($_->get_value("macAddress"), @entries);
65 @entries = map ("macaddress LIKE '$_'", @entries);
67 my ($hit, $hash, $db_res, $out_msg);
68 # Check known clients if a terminal server is active
69 $db_res = $main::known_clients_db->select_dbentry("SELECT * FROM $main::known_clients_tn WHERE ".join(" AND ", @entries));
70 while (($hit, $hash) = each %$db_res)
71 {
72 $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
73 push(@out_msg_l, $out_msg);
74 }
75 # Check foreign_clients if a terminal server is active
76 $db_res = $main::foreign_clients_db->select_dbentry("SELECT * FROM $main::foreign_clients_tn WHERE ".join(" AND ", @entries));
77 while (($hit, $hash) = each %$db_res)
78 {
79 $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
80 push(@out_msg_l, $out_msg);
81 }
83 ### JUST FOR DEBUGGING # CAN BE DELETED AT ANY TIME ###########################
84 # my $db_res = $main::known_clients_db->select_dbentry("SELECT * FROM $main::known_clients_tn WHERE macaddress LIKE '00:01:6c:9d:b9:fa'");
85 # while (($hit, $hash) = each %$db_res)
86 # {
87 # $out_msg = &create_xml_string(&create_xml_hash('get_load', $source, $hash->{macaddress}));
88 # push(@out_msg_l, $out_msg);
89 # }
90 ### JUST FOR DEBUGGING # CAN BE DELETED AT ANY TIME ###########################
92 # Found terminal server but no running clients on them
93 if (@out_msg_l == 0)
94 {
95 &main::daemon_log("$session_id ERROR: Found no running clients (known_clients_db, foreign_clients_db) on the following determined terminal server", 1);
96 my @entries = $ldap_mesg->entries;
97 foreach my $ts (@entries)
98 {
99 my $ip = (defined $ts->get_value("ipHostNumber")) ? " ip='".$ts->get_value("ipHostNumber")."'" : "" ;
100 my $cn = (defined $ts->get_value("cn")) ? " cn='".$ts->get_value("cn")."'" : "" ;
101 my $mac = (defined $ts->get_value("macAddress")) ? " macAddress='".$ts->get_value("macAddress")."'" : "" ;
102 &main::daemon_log("$session_id ERROR: ".$cn.$mac.$ip , 1);
103 }
104 }
106 }
107 # No terminal server found in LDAP
108 if ($ldap_mesg->count == 0)
109 {
110 &main::daemon_log("$session_id ERROR: No terminal server found in LDAP: \n\tbase='$ldap_base'\n\tscope='sub'\n\tattrs='['macAddress']'\n\tfilter='objectClass=goTerminalServer'", 1);
111 }
113 # Translating errors ?
114 if ($ldap_mesg->code)
115 {
116 &main::daemon_log("$session_id ERROR: Cannot fetch terminal server from LDAP: \n\tbase='$ldap_base'\n\tscope='sub'\n\tattrs='['macAddress']'\n\tfilter='objectClass=goTerminalServer'", 1);
117 }
118 }
119 &main::release_ldap_handle($ldap_handle);
121 return @out_msg_l;
122 }
125 sub get_events {
126 return \@events;
127 }
129 sub reload_ldap_config {
130 my ($msg, $msg_hash, $session_id) = @_;
131 my $header = @{$msg_hash->{header}}[0];
132 my $target = @{$msg_hash->{$header}}[0];
134 my $out_msg = &ClientPackages::new_ldap_config($target, $session_id);
135 my @out_msg_l = ( $out_msg );
136 return @out_msg_l;
137 }
140 sub got_ping {
141 my ($msg, $msg_hash, $session_id) = @_;
143 my $source = @{$msg_hash->{source}}[0];
144 my $target = @{$msg_hash->{target}}[0];
145 my $header = @{$msg_hash->{header}}[0];
146 my $act_time = &get_time;
147 my @out_msg_l;
148 my $out_msg;
150 $session_id = @{$msg_hash->{'session_id'}}[0];
152 # check known_clients_db
153 my $sql_statement = "SELECT * FROM known_clients WHERE hostname='$source'";
154 my $query_res = $main::known_clients_db->select_dbentry( $sql_statement );
155 if( 1 == keys %{$query_res} ) {
156 my $sql_statement= "UPDATE known_clients ".
157 "SET status='$header', timestamp='$act_time' ".
158 "WHERE hostname='$source'";
159 my $res = $main::known_clients_db->update_dbentry( $sql_statement );
160 }
162 # check known_server_db
163 $sql_statement = "SELECT * FROM known_server WHERE hostname='$source'";
164 $query_res = $main::known_server_db->select_dbentry( $sql_statement );
165 if( 1 == keys %{$query_res} ) {
166 my $sql_statement= "UPDATE known_server ".
167 "SET status='$header', timestamp='$act_time' ".
168 "WHERE hostname='$source'";
169 my $res = $main::known_server_db->update_dbentry( $sql_statement );
170 }
172 # create out_msg
173 my $out_hash = &create_xml_hash($header, $source, "GOSA");
174 &add_content2xml_hash($out_hash, "session_id", $session_id);
175 $out_msg = &create_xml_string($out_hash);
176 my $forward_to_gosa = @{$msg_hash->{'forward_to_gosa'}}[0];
177 if (defined $forward_to_gosa) {
178 $out_msg =~s/<\/xml>/<forward_to_gosa>$forward_to_gosa<\/forward_to_gosa><\/xml>/;
179 }
180 push(@out_msg_l, $out_msg);
182 return @out_msg_l;
183 }
186 sub detected_hardware {
187 my ($msg, $msg_hash, $session_id) = @_;
188 my $address = $msg_hash->{source}[0];
189 my $header = $msg_hash->{header}[0];
190 my $gotoHardwareChecksum= $msg_hash->{detected_hardware}[0]->{gotoHardwareChecksum};
192 my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'";
193 my $res = $main::known_clients_db->select_dbentry( $sql_statement );
195 # check hit
196 my $hit_counter = keys %{$res};
197 if( not $hit_counter == 1 ) {
198 &main::daemon_log("$session_id ERROR: more or no hit found in known_clients_db by query by '$address'", 1);
199 return;
200 }
202 my $macaddress = $res->{1}->{macaddress};
203 my $hostkey = $res->{1}->{hostkey};
205 if (not defined $macaddress) {
206 &main::daemon_log("$session_id ERROR: no mac address found for client $address", 1);
207 return;
208 }
210 # Perform search
211 my $ldap_handle = &main::get_ldap_handle();
212 $mesg = $ldap_handle->search(
213 base => $ldap_base,
214 scope => 'sub',
215 filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))"
216 );
218 # We need to create a base entry first (if not done from ArpHandler)
219 if($mesg->count == 0) {
220 &main::daemon_log("INFO: Need to create a new LDAP Entry for client $address", 4);
221 my $ipaddress= $1 if $address =~ /^([0-9\.]*?):.*$/;
222 my $dnsname;
223 #FIXME: like in ClientPackages!
224 #if ( defined($heap->{force-hostname}->{$macaddress}) ){
225 # $dnsname= $heap->{force-hostname}->{$macaddress};
226 # &main::daemon_log("INFO: Using forced hostname $dnsname for client $address", 4);
227 if (-e "/var/tmp/$macaddress" ){
228 open(TFILE, "< /var/tmp/$macaddress");
229 $dnsname= <TFILE>;
230 close(TFILE);
231 } else {
232 $dnsname= gethostbyaddr(inet_aton($ipaddress), AF_INET) || $ipaddress;
233 }
235 my $cn = (($dnsname =~ /^(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}/) ? $dnsname : sprintf "%s", $dnsname =~ /([^\.]+)\.?/);
236 my $dn = "cn=$cn,ou=incoming,$ldap_base";
237 &main::daemon_log("INFO: Creating entry for $dn",5);
238 my $entry= Net::LDAP::Entry->new( $dn );
239 $entry->dn($dn);
240 $entry->add("objectClass" => "GOhard");
241 $entry->add("cn" => $cn);
242 $entry->add("macAddress" => $macaddress);
243 $entry->add("gotomode" => "locked");
244 $entry->add("gotoSysStatus" => "new-system");
245 $entry->add("ipHostNumber" => $ipaddress);
246 if(defined($main::gosa_unit_tag) && length($main::gosa_unit_tag) > 0) {
247 $entry->add("objectClass" => "gosaAdministrativeUnitTag");
248 $entry->add("gosaUnitTag" => $main::gosa_unit_tag);
249 }
250 my $res=$entry->update($ldap_handle);
251 if(defined($res->{'errorMessage'}) &&
252 length($res->{'errorMessage'}) >0) {
253 &main::daemon_log("ERROR: can not add entries to LDAP: ".$res->{'errorMessage'}, 1);
254 &main::release_ldap_handle($ldap_handle);
255 return;
256 } else {
257 # Fill $mesg again
258 $mesg = $ldap_handle->search(
259 base => $ldap_base,
260 scope => 'sub',
261 filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))"
262 );
263 }
264 }
266 if($mesg->count == 1) {
267 my $entry= $mesg->entry(0);
268 $entry->changetype("modify");
269 foreach my $attribute (
270 "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel",
271 "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync",
272 "gotoXDriver", "gotoXVsync", "gotoXMonitor", "gotoHardwareChecksum") {
273 if(defined($msg_hash->{detected_hardware}[0]->{$attribute}) &&
274 length($msg_hash->{detected_hardware}[0]->{$attribute}) >0 ) {
275 if(defined($entry->get_value($attribute))) {
276 $entry->delete($attribute => []);
277 }
278 &main::daemon_log("INFO: Adding attribute $attribute with value ".$msg_hash->{detected_hardware}[0]->{$attribute},5);
279 $entry->add($attribute => $msg_hash->{detected_hardware}[0]->{$attribute});
280 }
281 }
282 foreach my $attribute (
283 "gotoModules", "ghScsiDev", "ghIdeDev") {
284 if(defined($msg_hash->{detected_hardware}[0]->{$attribute}) &&
285 length($msg_hash->{detected_hardware}[0]->{$attribute}) >0 ) {
286 if(defined($entry->get_value($attribute))) {
287 $entry->delete($attribute => []);
288 }
289 foreach my $array_entry (keys %{{map { $_ => 1 } sort(@{$msg_hash->{detected_hardware}[0]->{$attribute}}) }}) {
290 $entry->add($attribute => $array_entry);
291 }
292 }
293 }
295 my $res=$entry->update($ldap_handle);
296 if(defined($res->{'errorMessage'}) &&
297 length($res->{'errorMessage'}) >0) {
298 &main::daemon_log("ERROR: can not add entries to LDAP: ".$res->{'errorMessage'}, 1);
299 } else {
300 &main::daemon_log("INFO: Added Hardware configuration to LDAP", 5);
301 }
302 }
304 # if there is a job in job queue for this host and this macaddress, delete it, cause its no longer used
305 my $del_sql = "DELETE FROM $main::job_queue_tn WHERE (macaddress LIKE '$macaddress' AND headertag='$header')";
306 my $del_res = $main::job_db->exec_statement($del_sql);
307 &main::release_ldap_handle($ldap_handle);
309 return ;
310 }
312 1;