X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fmodules%2FSIPackages.pm;h=4f7bd8611dedec2cd1dae64768424fa369a409f7;hb=1bf6d6303fb62f5b51b9ebff12524f7631a02bc7;hp=65be05af8d3515da1ff044029b9703d45efb6716;hpb=481cff0026ee3f48ae783df4e6ea628c0cc15815;p=gosa.git diff --git a/gosa-si/modules/SIPackages.pm b/gosa-si/modules/SIPackages.pm index 65be05af8..4f7bd8611 100644 --- a/gosa-si/modules/SIPackages.pm +++ b/gosa-si/modules/SIPackages.pm @@ -16,18 +16,21 @@ use NetAddr::IP; use Net::LDAP; use Socket; use Net::hostent; -use Net::DNS; + +my $event_dir = "/usr/lib/gosa-si/server/events"; +use lib "/usr/lib/gosa-si/server/events"; BEGIN{} END {} -my ($server_ip, $server_mac_address, $server_port, $SIPackages_key, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $server_interface); +my ($server_ip, $server_port, $SIPackages_key, $max_clients, $ldap_uri, $ldap_base, $ldap_admin_dn, $ldap_admin_password, $server_interface); my ($bus_activ, $bus_key, $bus_ip, $bus_port); my $server; +my $event_hash; my $network_interface; my $no_bus; my (@ldap_cfg, @pam_cfg, @nss_cfg, $goto_admin, $goto_secret); - +my $mesg; my %cfg_defaults = ( "bus" => { @@ -38,13 +41,13 @@ my %cfg_defaults = ( }, "server" => { "ip" => [\$server_ip, "0.0.0.0"], - "mac_address" => [\$server_mac_address, "00:00:00:00:00"], + "mac-address" => [\$main::server_mac_address, "00:00:00:00:00"], "port" => [\$server_port, "20081"], - "ldap_uri" => [\$ldap_uri, ""], - "ldap_base" => [\$ldap_base, ""], - "ldap_admin_dn" => [\$ldap_admin_dn, ""], - "ldap_admin_password" => [\$ldap_admin_password, ""], - "max_clients" => [\$max_clients, 100], + "ldap-uri" => [\$ldap_uri, ""], + "ldap-base" => [\$ldap_base, ""], + "ldap-admin-dn" => [\$ldap_admin_dn, ""], + "ldap-admin-password" => [\$ldap_admin_password, ""], + "max-clients" => [\$max_clients, 100], }, "SIPackages" => { "key" => [\$SIPackages_key, ""], @@ -56,15 +59,95 @@ my %cfg_defaults = ( # read configfile and import variables &read_configfile(); + +# if server_ip is not an ip address but a name +if( inet_aton($server_ip) ){ $server_ip = inet_ntoa(inet_aton($server_ip)); } $network_interface= &get_interface_for_ip($server_ip); -$server_mac_address= &get_mac($network_interface); +$main::server_mac_address= &get_mac($network_interface); + +&import_events(); + +# Unit tag can be defined in config +if((not defined($main::gosa_unit_tag)) || length($main::gosa_unit_tag) == 0) { + # Read gosaUnitTag from LDAP + + my $ldap_handle = &main::get_ldap_handle(); + if( defined($ldap_handle) ) { + &main::daemon_log("INFO: Searching for servers gosaUnitTag with mac address $main::server_mac_address",5); + # Perform search for Unit Tag + $mesg = $ldap_handle->search( + base => $ldap_base, + scope => 'sub', + attrs => ['gosaUnitTag'], + filter => "(macaddress=$main::server_mac_address)" + ); + + if ($mesg->count == 1) { + my $entry= $mesg->entry(0); + my $unit_tag= $entry->get_value("gosaUnitTag"); + $main::ldap_server_dn= $mesg->entry(0)->dn; + if(defined($unit_tag) && length($unit_tag) > 0) { + &main::daemon_log("INFO: Detected gosaUnitTag $unit_tag for creating entries", 5); + $main::gosa_unit_tag= $unit_tag; + } + } else { + # Perform another search for Unit Tag + my $hostname= `hostname -f`; + chomp($hostname); + &main::daemon_log("INFO: Searching for servers gosaUnitTag with hostname $hostname",5); + $mesg = $ldap_handle->search( + base => $ldap_base, + scope => 'sub', + attrs => ['gosaUnitTag'], + filter => "(&(cn=$hostname)(objectClass=goServer))" + ); + if ($mesg->count == 1) { + my $entry= $mesg->entry(0); + my $unit_tag= $entry->get_value("gosaUnitTag"); + $main::ldap_server_dn= $mesg->entry(0)->dn; + if(defined($unit_tag) && length($unit_tag) > 0) { + &main::daemon_log("INFO: Detected gosaUnitTag $unit_tag for creating entries", 5); + $main::gosa_unit_tag= $unit_tag; + } + } else { + # Perform another search for Unit Tag + $hostname= `hostname -s`; + chomp($hostname); + &main::daemon_log("INFO: Searching for servers gosaUnitTag with hostname $hostname",5); + $mesg = $ldap_handle->search( + base => $ldap_base, + scope => 'sub', + attrs => ['gosaUnitTag'], + filter => "(&(cn=$hostname)(objectClass=goServer))" + ); + if ($mesg->count == 1) { + my $entry= $mesg->entry(0); + my $unit_tag= $entry->get_value("gosaUnitTag"); + $main::ldap_server_dn= $mesg->entry(0)->dn; + if(defined($unit_tag) && length($unit_tag) > 0) { + &main::daemon_log("INFO: Detected gosaUnitTag $unit_tag for creating entries", 5); + $main::gosa_unit_tag= $unit_tag; + } + } else { + &main::daemon_log("WARNING: No gosaUnitTag detected. Not using gosaUnitTag", 3); + } + } + } + } else { + &main::daemon_log("INFO: Using gosaUnitTag from config-file: $main::gosa_unit_tag",5); + } +} + -# complete addresses -#if( $server_ip eq "0.0.0.0" ) { -# $server_ip = "127.0.0.1"; -#} my $server_address = "$server_ip:$server_port"; $main::server_address = $server_address; + + +if( inet_aton($bus_ip) ){ $bus_ip = inet_ntoa(inet_aton($bus_ip)); } +###################################################### +# to change +if( $bus_ip eq "127.0.1.1" ) { $bus_ip = "127.0.0.1" } +###################################################### my $bus_address = "$bus_ip:$bus_port"; $main::bus_address = $bus_address; @@ -81,7 +164,7 @@ if($bus_activ eq "on") { # add myself to known_server_db my $res = $main::known_server_db->add_dbentry( {table=>'known_server', - primkey=>'hostname', + primkey=>['hostname'], hostname=>$server_address, status=>'myself', hostkey=>$SIPackages_key, @@ -101,54 +184,6 @@ sub get_module_info { } -sub do_wake { - my $host = shift; - my $ipaddr = shift || '255.255.255.255'; - my $port = getservbyname('discard', 'udp'); - - my ($raddr, $them, $proto); - my ($hwaddr, $hwaddr_re, $pkt); - - # get the hardware address (ethernet address) - - $hwaddr_re = join(':', ('[0-9A-Fa-f]{1,2}') x 6); - if ($host =~ m/^$hwaddr_re$/) { - $hwaddr = $host; - } else { - # $host is not a hardware address, try to resolve it - my $ip_re = join('\.', ('([0-9]|[1-9][0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))') x 4); - my $ip_addr; - if ($host =~ m/^$ip_re$/) { - $ip_addr = $host; - } else { - my $h; - unless ($h = gethost($host)) { - return undef; - } - $ip_addr = inet_ntoa($h->addr); - } - } - - # Generate magic sequence - foreach (split /:/, $hwaddr) { - $pkt .= chr(hex($_)); - } - $pkt = chr(0xFF) x 6 . $pkt x 16; - - # Allocate socket and send packet - - $raddr = gethostbyname($ipaddr)->addr; - $them = pack_sockaddr_in($port, $raddr); - $proto = getprotobyname('udp'); - - socket(S, AF_INET, SOCK_DGRAM, $proto) or die "socket : $!"; - setsockopt(S, SOL_SOCKET, SO_BROADCAST, 1) or die "setsockopt : $!"; - - send(S, $pkt, 0, $them) or die "send : $!"; - close S; -} - - #=== FUNCTION ================================================================ # NAME: read_configfile # PARAMETERS: cfg_file - string - @@ -216,7 +251,7 @@ sub get_interface_for_ip { } else { foreach (@ifs) { my $if=$_; - if(get_ip($if) eq $ip) { + if(&main::get_ip($if) eq $ip) { $result = $if; } } @@ -272,8 +307,8 @@ sub get_mac { my $SIOCGIFHWADDR= 0x8927; # man 2 ioctl_list # A configured MAC Address should always override a guessed value - if ($server_mac_address and length($server_mac_address) > 0) { - $result= $server_mac_address; + if ($main::server_mac_address and length($main::server_mac_address) > 0) { + $result= $main::server_mac_address; } socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip') @@ -304,7 +339,7 @@ sub register_at_bus { # add bus to known_server_db my $res = $main::known_server_db->add_dbentry( {table=>'known_server', - primkey=>'hostname', + primkey=>['hostname'], hostname=>$bus_address, status=>'bus', hostkey=>$bus_key, @@ -318,6 +353,35 @@ sub register_at_bus { } +sub import_events { + if (not -e $event_dir) { + &main::daemon_log("S ERROR: cannot find directory or directory is not readable: $event_dir", 1); + } + opendir (DIR, $event_dir) or die "ERROR while loading gosa-si-events from directory $event_dir : $!\n"; + + while (defined (my $event = readdir (DIR))) { + if( $event eq "." || $event eq ".." ) { next; } + if( $event eq "gosaTriggered.pm" ) { next; } # only GOsa specific events + + eval{ require $event; }; + if( $@ ) { + &main::daemon_log("import of event module '$event' failed", 1); + &main::daemon_log("$@", 8); + next; + } + + $event =~ /(\S*?).pm$/; + my $event_module = $1; + my $events_l = eval( $1."::get_events()") ; + foreach my $event_name (@{$events_l}) { + $event_hash->{$event_name} = $event_module; + } + my $events_string = join( ", ", @{$events_l}); + &main::daemon_log("S DEBUG: SIPackages imported events $events_string", 8); + } +} + + #=== FUNCTION ================================================================ # NAME: process_incoming_msg # PARAMETERS: crypted_msg - string - incoming crypted message @@ -325,91 +389,63 @@ sub register_at_bus { # DESCRIPTION: handels the proceeded distribution to the appropriated functions #=============================================================================== sub process_incoming_msg { - my ($msg, $msg_hash, $remote_ip) = @_ ; + my ($msg, $msg_hash, $session_id) = @_ ; my $error = 0; my $host_name; my $host_key; - my @out_msg_l; + my @out_msg_l = ("nohandler"); # process incoming msg my $header = @{$msg_hash->{header}}[0]; my @target_l = @{$msg_hash->{target}}; - &main::daemon_log("SIPackages: msg to process: $header", 3); - &main::daemon_log("$msg", 8); + # skip PREFIX + $header =~ s/^CLMSG_//; + + &main::daemon_log("$session_id DEBUG: SIPackages: msg to process: $header", 7); if( 0 == length @target_l){ - &main::daemon_log("ERROR: no target specified for msg $header", 1); + &main::daemon_log("$session_id ERROR: no target specified for msg $header", 1); $error++; } if( 1 == length @target_l) { my $target = $target_l[0]; if(&server_matches($target)) { + + if ($header eq 'new_key') { @out_msg_l = &new_key($msg_hash) } elsif ($header eq 'here_i_am') { - @out_msg_l = &here_i_am($msg_hash) - } elsif ($header eq 'who_has') { - @out_msg_l = &who_has($msg_hash) - } elsif ($header eq 'who_has_i_do') { - @out_msg_l = &who_has_i_do($msg_hash) - } elsif ($header eq 'got_ping') { - @out_msg_l = &got_ping($msg_hash) - } elsif ($header eq 'get_load') { - @out_msg_l = &execute_actions($msg_hash) - } elsif ($header eq 'detected_hardware') { - @out_msg_l = &process_detected_hardware($msg_hash) - } elsif ($header eq 'trigger_wake') { - foreach (@{$msg_hash->{macAddress}}){ - &main::daemon_log("SIPackages: trigger wake for $_", 1); - do_wake($_); - } - + @out_msg_l = &here_i_am($msg, $msg_hash, $session_id) } else { - &main::daemon_log("ERROR: $header is an unknown core function", 1); - $error++; + if( exists $event_hash->{$header} ) { + # a event exists with the header as name + &main::daemon_log("$session_id INFO: found event '$header' at event-module '".$event_hash->{$header}."'", 5); + no strict 'refs'; + @out_msg_l = &{$event_hash->{$header}."::$header"}($msg, $msg_hash, $session_id); + } } + + # if delivery not possible raise error and return + if( not defined $out_msg_l[0] ) { + @out_msg_l = (); + } elsif( $out_msg_l[0] eq 'nohandler') { + &main::daemon_log("$session_id ERROR: SIPackages: no event handler or core function defined for '$header'", 1); + @out_msg_l = (); + } + } else { - &main::daemon_log("msg is not for gosa-si-server '$server_address', deliver it to target '$target'", 5); + &main::daemon_log("INFO: msg is not for gosa-si-server '$server_address', deliver it to target '$target'", 5); push(@out_msg_l, $msg); } } -# if( $error == 0) { -# if( 0 == @out_msg_l ) { -# push(@out_msg_l, $msg); -# } -# } - return \@out_msg_l; } -#=== FUNCTION ================================================================ -# NAME: got_ping -# PARAMETERS: msg_hash - hash - hash from function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: process this incoming message -#=============================================================================== -sub got_ping { - my ($msg_hash) = @_; - - my $source = @{$msg_hash->{source}}[0]; - my $target = @{$msg_hash->{target}}[0]; - my $header = @{$msg_hash->{header}}[0]; - - if(exists $main::known_daemons->{$source}) { - &main::add_content2known_daemons(hostname=>$source, status=>$header); - } else { - &main::add_content2known_clients(hostname=>$source, status=>$header); - } - - return; -} - - #=== FUNCTION ================================================================ # NAME: new_passwd # PARAMETERS: msg_hash - ref - hash from function create_xml_hash @@ -468,7 +504,7 @@ sub new_key { # DESCRIPTION: process this incoming message #=============================================================================== sub here_i_am { - my ($msg_hash) = @_; + my ($msg, $msg_hash, $session_id) = @_; my @out_msg_l; my $out_hash; @@ -484,16 +520,16 @@ sub here_i_am { my $db_res= $main::known_clients_db->select_dbentry( $sql_statement ); if ( 1 == keys %{$db_res} ) { - &main::daemon_log("WARNING: $source is already known as a client", 1); - &main::daemon_log("WARNING: values for $source are being overwritten", 1); + &main::daemon_log("$session_id WARNING: $source is already known as a client", 1); + &main::daemon_log("$session_id WARNING: values for $source are being overwritten", 1); $nu_clients --; } # number of actual activ clients my $act_nu_clients = $nu_clients; - &main::daemon_log("number of actual activ clients: $act_nu_clients", 5); - &main::daemon_log("number of maximal allowed clients: $max_clients", 5); + &main::daemon_log("$session_id INFO: number of actual activ clients: $act_nu_clients", 5); + &main::daemon_log("$session_id INFO: number of maximal allowed clients: $max_clients", 5); if($max_clients <= $act_nu_clients) { my $out_hash = &create_xml_hash("denied", $server_address, $source); @@ -513,7 +549,7 @@ sub here_i_am { # add entry to known_clients_db my $act_timestamp = &get_time; my $res = $main::known_clients_db->add_dbentry( {table=>'known_clients', - primkey=>'hostname', + primkey=>['hostname'], hostname=>$source, events=>$events, macaddress=>$mac_address, @@ -523,14 +559,12 @@ sub here_i_am { } ); if ($res != 0) { - &main::daemon_log("ERROR: cannot add entry to known_clients: $res"); + &main::daemon_log("$session_id ERROR: cannot add entry to known_clients: $res"); return; } # return acknowledgement to client $out_hash = &create_xml_hash("registered", $server_address, $source); - my $register_out = &create_xml_string($out_hash); - push(@out_msg_l, $register_out); # notify registered client to bus if( $bus_activ eq "on") { @@ -545,16 +579,32 @@ sub here_i_am { &add_content2xml_hash($out_hash, "timestamp", $act_timestamp); my $new_client_out = &create_xml_string($out_hash); push(@out_msg_l, $new_client_out); - &main::daemon_log("send bus msg that client '$source' has registerd at server '$server_address'", 3); + &main::daemon_log("$session_id INFO: send bus msg that client '$source' has registered at server '$server_address'", 5); } # give the new client his ldap config - my $new_ldap_config_out = &new_ldap_config($source); - if( $new_ldap_config_out ) { - push(@out_msg_l, $new_ldap_config_out); + # Workaround: Send within the registration response, if the client will get an ldap config later + my $new_ldap_config_out = &new_ldap_config($source, $session_id); + if($new_ldap_config_out && (!($new_ldap_config_out =~ /error/))) { + &add_content2xml_hash($out_hash, "ldap_available", "true"); + } elsif($new_ldap_config_out && $new_ldap_config_out =~ /error/){ + &add_content2xml_hash($out_hash, "error", $new_ldap_config_out); + + my $sql_statement = "UPDATE $main::job_queue_tn ". + "SET status='error', result='$new_ldap_config_out' ". + "WHERE status='processing' AND macaddress LIKE '$mac_address'"; + my $res = $main::job_db->update_dbentry($sql_statement); + &main::daemon_log("$session_id DEBUG: $sql_statement RESULT: $res", 7); + } + my $register_out = &create_xml_string($out_hash); + push(@out_msg_l, $register_out); + + # Really send the ldap config + if( $new_ldap_config_out && (!($new_ldap_config_out =~ /error/))) { + push(@out_msg_l, $new_ldap_config_out); } - my $hardware_config_out = &hardware_config($source, $gotoHardwareChecksum); + my $hardware_config_out = &hardware_config($msg, $msg_hash, $session_id); if( $hardware_config_out ) { push(@out_msg_l, $hardware_config_out); } @@ -611,61 +661,59 @@ sub who_has_i_do { print "\ngot msg $header:\nserver $source has client with $search_param $search_value\n"; } + #=== FUNCTION ================================================================ # NAME: new_ldap_config # PARAMETERS: address - string - ip address and port of a host -# RETURNS: nothing +# RETURNS: gosa-si conform message # DESCRIPTION: send to address the ldap configuration found for dn gotoLdapServer #=============================================================================== sub new_ldap_config { - my ($address) = @_ ; + my ($address, $session_id) = @_ ; - my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'"; + my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address' OR macaddress LIKE '$address'"; my $res = $main::known_clients_db->select_dbentry( $sql_statement ); # check hit my $hit_counter = keys %{$res}; if( not $hit_counter == 1 ) { - &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1); + &main::daemon_log("$session_id ERROR: more or no hit found in known_clients_db by query by '$address'", 1); } + $address = $res->{1}->{hostname}; my $macaddress = $res->{1}->{macaddress}; my $hostkey = $res->{1}->{hostkey}; if (not defined $macaddress) { - &main::daemon_log("ERROR: no mac address found for client $address", 1); + &main::daemon_log("$session_id ERROR: no mac address found for client $address", 1); return; } # Build LDAP connection - my $ldap = Net::LDAP->new($ldap_uri); - if( not defined $ldap ) { - &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1); + my $ldap_handle = &main::get_ldap_handle($session_id); + if( not defined $ldap_handle ) { + &main::daemon_log("$session_id ERROR: cannot connect to ldap: $ldap_uri", 1); return; } - - # Bind to a directory with dn and password - my $mesg= $ldap->bind($ldap_admin_dn, password => $ldap_admin_password); - # Perform search - $mesg = $ldap->search( base => $ldap_base, + $mesg = $ldap_handle->search( base => $ldap_base, scope => 'sub', - attrs => ['dn', 'gotoLdapServer', 'gosaUnitTag'], - filter => "(&(objectClass=GOhard)(macaddress=$macaddress))"); + attrs => ['dn', 'gotoLdapServer', 'gosaUnitTag', 'FAIclass'], + filter => "(&(objectClass=GOhard)(macaddress=$macaddress)(gotoLdapServer=*))"); #$mesg->code && die $mesg->error; if($mesg->code) { - &main::daemon_log($mesg->error, 1); + &main::daemon_log("$session_id ".$mesg->error, 1); return; } # Sanity check if ($mesg->count != 1) { - &main::daemon_log("WARNING: client mac address $macaddress not found/not unique in ldap search", 1); - &main::daemon_log("\tbase: $ldap_base", 1); - &main::daemon_log("\tscope: sub", 1); - &main::daemon_log("\tattrs: dn, gotoLdapServer", 1); - &main::daemon_log("\tfilter: (&(objectClass=GOhard)(macaddress=$macaddress))", 1); + &main::daemon_log("$session_id WARNING: client with mac address $macaddress not found/unique/active - not sending ldap config". + "\n\tbase: $ldap_base". + "\n\tscope: sub". + "\n\tattrs: dn, gotoLdapServer". + "\n\tfilter: (&(objectClass=GOhard)(macaddress=$macaddress)(gotoLdapServer=*))", 1); return; } @@ -676,42 +724,68 @@ sub new_ldap_config { my @ldap_uris; my $server; my $base; + my $release; + + # Fill release if available + my $FAIclass= $entry->get_value("FAIclass"); + if (defined $FAIclass && $FAIclass =~ /^.* :([A-Za-z0-9\/.]+).*$/) { + $release= $1; + } # Do we need to look at an object class? if (length(@servers) < 1){ - $mesg = $ldap->search( base => $ldap_base, + $mesg = $ldap_handle->search( base => $ldap_base, scope => 'sub', - attrs => ['dn', 'gotoLdapServer'], + attrs => ['dn', 'gotoLdapServer', 'FAIclass'], filter => "(&(objectClass=gosaGroupOfNames)(member=$dn))"); #$mesg->code && die $mesg->error; if($mesg->code) { - &main::daemon_log($mesg->error, 1); + &main::daemon_log("$session_id ".$mesg->error, 1); return; } # Sanity check if ($mesg->count != 1) { - &main::daemon_log("WARNING: no LDAP information found for client mac $macaddress", 1); + &main::daemon_log("$session_id WARNING: no LDAP information found for client mac $macaddress", 1); return; } $entry= $mesg->entry(0); $dn= $entry->dn; @servers= $entry->get_value("gotoLdapServer"); + + if (not defined $release){ + $FAIclass= $entry->get_value("FAIclass"); + if (defined $FAIclass && $FAIclass =~ /^.* :([A-Za-z0-9\/.]+).*$/) { + $release= $1; + } + } } @servers= sort (@servers); foreach $server (@servers){ - $base= $server; - $server =~ s%^[^:]+:[^:]+:(ldap.*://[^/]+)/.*$%$1%; - $base =~ s%^[^:]+:[^:]+:ldap.*://[^/]+/(.*)$%$1%; - push (@ldap_uris, $server); + # Conversation for backward compatibility + if (not $server =~ /^\d+:[^:]+:ldap[^:]*:\/\// ) { + if ($server =~ /^([^:]+):([^:]+)$/ ) { + $server= "1:dummy:ldap://$1/$2"; + } elsif ($server =~ /^(\d+):([^:]+):(.*)$/ ) { + $server= "$1:dummy:ldap://$2/$3"; + } + } + + $base= $server; + $server =~ s%^[^:]+:[^:]+:(ldap.*://[^/]+)/.*$%$1%; + $base =~ s%^[^:]+:[^:]+:ldap.*://[^/]+/(.*)$%$1%; + push (@ldap_uris, $server); } # Assemble data package my %data = ( 'ldap_uri' => \@ldap_uris, 'ldap_base' => $base, 'ldap_cfg' => \@ldap_cfg, 'pam_cfg' => \@pam_cfg,'nss_cfg' => \@nss_cfg ); + if (defined $release){ + $data{'release'}= $release; + } # Need to append GOto settings? if (defined $goto_admin and defined $goto_secret){ @@ -723,20 +797,20 @@ sub new_ldap_config { if (defined $unit_tag){ # Find admin base and department name - $mesg = $ldap->search( base => $ldap_base, + $mesg = $ldap_handle->search( base => $ldap_base, scope => 'sub', - attrs => ['dn', 'ou', 'FAIclass'], + attrs => ['dn', 'ou'], filter => "(&(objectClass=gosaAdministrativeUnit)(gosaUnitTag=$unit_tag))"); #$mesg->code && die $mesg->error; if($mesg->code) { &main::daemon_log($mesg->error, 1); - return; + return "error-unit-tag-count-0"; } # Sanity check if ($mesg->count != 1) { &main::daemon_log("WARNING: cannot find administrative unit for client with tag $unit_tag", 1); - return; + return "error-unit-tag-count-".$mesg->count; } $entry= $mesg->entry(0); @@ -747,125 +821,11 @@ sub new_ldap_config { $data{'unit_tag'}= $unit_tag; } - # Fill release if available - my $FAIclass= $entry->get_value("FAIclass"); - if (defined $FAIclass && $FAIclass =~ /^.* :([A-Za-z0-9\/.]+).*$/) { - $data{'release'}= $1; - } - - - # Unbind - $mesg = $ldap->unbind; - # Send information - return send_msg("new_ldap_config", $server_address, $address, \%data); + return &build_msg("new_ldap_config", $server_address, $address, \%data); } -sub process_detected_hardware { - my $msg_hash = shift; - my $address = $msg_hash->{source}[0]; - my $gotoHardwareChecksum= $msg_hash->{detected_hardware}[0]->{gotoHardwareChecksum}; - - my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'"; - my $res = $main::known_clients_db->select_dbentry( $sql_statement ); - - # check hit - my $hit_counter = keys %{$res}; - if( not $hit_counter == 1 ) { - &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1); - return; - } - - my $macaddress = $res->{1}->{macaddress}; - my $hostkey = $res->{1}->{hostkey}; - - if (not defined $macaddress) { - &main::daemon_log("ERROR: no mac address found for client $address", 1); - return; - } - # Build LDAP connection - my $ldap = Net::LDAP->new($ldap_uri); - if( not defined $ldap ) { - &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1); - return; - } - - # Bind to a directory with dn and password - my $mesg= $ldap->bind($ldap_admin_dn, password => $ldap_admin_password); - - # Perform search - $mesg = $ldap->search( - base => $ldap_base, - scope => 'sub', - filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))" - ); - - # We need to create a base entry first (if not done from ArpHandler) - if($mesg->count == 0) { - &main::daemon_log("Need to create a new LDAP Entry for client $address", 1); - my $resolver=Net::DNS::Resolver->new; - my $ipaddress= $1 if $address =~ /^([0-9\.]*?):.*$/; - my $dnsresult= $resolver->search($ipaddress); - my $dnsname= (defined($dnsresult))?$dnsresult->{answer}[0]->{ptrdname}:$ipaddress; - my $cn = (($dnsname =~ /^(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}/) ? $dnsname : sprintf "%s", $dnsname =~ /([^\.]+)\.?/); - my $dn = "cn=$cn,ou=incoming,$ldap_base"; - &main::daemon_log("Creating entry for $dn",6); - my $entry= Net::LDAP::Entry->new( $dn ); - $entry->dn($dn); - $entry->add("objectClass" => "goHard"); - $entry->add("cn" => $cn); - $entry->add("macAddress" => $macaddress); - $entry->add("gotomode" => "locked"); - $entry->add("gotoSysStatus" => "new-system"); - $entry->add("ipHostNumber" => $ipaddress); - if(my $res=$entry->update($ldap)) { - # Fill $mesg again - $mesg = $ldap->search( - base => $ldap_base, - scope => 'sub', - filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))" - ); - } else { - &main::daemon_log("ERROR: There was a problem adding the entry", 1); - } - } - - if($mesg->count == 1) { - my $entry= $mesg->entry(0); - $entry->changetype("modify"); - foreach my $attribute ( - "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel", - "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync", - "gotoXDriver", "gotoXVsync", "gotoXMonitor", "gotoHardwareChecksum") { - if(defined($msg_hash->{detected_hardware}[0]->{$attribute})) { - if(defined($entry->get_value($attribute))) { - $entry->delete($attribute); - } - &main::daemon_log("Adding attribute $attribute with value ".$msg_hash->{detected_hardware}[0]->{$attribute},1); - $entry->add($attribute => $msg_hash->{detected_hardware}[0]->{$attribute}); - } - } - foreach my $attribute ( - "gotoModules", "ghScsiDev", "ghIdeDev") { - if(defined($msg_hash->{detected_hardware}[0]->{$attribute})) { - if(defined($entry->get_value($attribute))) { - $entry->delete($attribute); - } - foreach my $array_entry (@{$msg_hash->{detected_hardware}[0]->{$attribute}}) { - $entry->add($attribute => $array_entry); - } - } - - } - - if($entry->update($ldap)) { - &main::daemon_log("Added Hardware configuration to LDAP", 4); - } - - } - return; -} #=== FUNCTION ================================================================ # NAME: hardware_config # PARAMETERS: address - string - ip address and port of a host @@ -873,7 +833,10 @@ sub process_detected_hardware { # DESCRIPTION: #=============================================================================== sub hardware_config { - my ($address, $gotoHardwareChecksum) = @_ ; + my ($msg, $msg_hash, $session_id) = @_ ; + my $address = @{$msg_hash->{source}}[0]; + my $header = @{$msg_hash->{header}}[0]; + my $gotoHardwareChecksum = @{$msg_hash->{gotoHardwareChecksum}}[0]; my $sql_statement= "SELECT * FROM known_clients WHERE hostname='$address'"; my $res = $main::known_clients_db->select_dbentry( $sql_statement ); @@ -881,29 +844,25 @@ sub hardware_config { # check hit my $hit_counter = keys %{$res}; if( not $hit_counter == 1 ) { - &main::daemon_log("ERROR: more or no hit found in known_clients_db by query by '$address'", 1); + &main::daemon_log("$session_id ERROR: more or no hit found in known_clients_db by query by '$address'", 1); } - my $macaddress = $res->{1}->{macaddress}; my $hostkey = $res->{1}->{hostkey}; if (not defined $macaddress) { - &main::daemon_log("ERROR: no mac address found for client $address", 1); + &main::daemon_log("$session_id ERROR: no mac address found for client $address", 1); return; } # Build LDAP connection - my $ldap = Net::LDAP->new($ldap_uri); - if( not defined $ldap ) { - &main::daemon_log("ERROR: cannot connect to ldap: $ldap_uri", 1); + my $ldap_handle = &main::get_ldap_handle($session_id); + if( not defined $ldap_handle ) { + &main::daemon_log("$session_id ERROR: cannot connect to ldap: $ldap_uri", 1); return; } - # Bind to a directory with dn and password - my $mesg= $ldap->bind($ldap_admin_dn, password => $ldap_admin_password); - # Perform search - $mesg = $ldap->search( + $mesg = $ldap_handle->search( base => $ldap_base, scope => 'sub', filter => "(&(objectClass=GOhard)(|(macAddress=$macaddress)(dhcpHWaddress=ethernet $macaddress)))" @@ -911,69 +870,37 @@ sub hardware_config { if($mesg->count() == 0) { &main::daemon_log("Host was not found in LDAP!", 1); + + # set status = hardware_detection at jobqueue if entry exists + my $func_dic = {table=>$main::job_queue_tn, + primkey=>['id'], + timestamp=>&get_time, + status=>'processing', + result=>'none', + progress=>'hardware-detection', + headertag=>'trigger_action_reinstall', + targettag=>$address, + xmlmessage=>'none', + macaddress=>$macaddress, + }; + my $hd_res = $main::job_db->add_dbentry($func_dic); + &main::daemon_log("$session_id INFO: add '$macaddress' to job queue as an installing job", 5); + } else { my $entry= $mesg->entry(0); my $dn= $entry->dn; - if(defined($entry->get_value("gotoHardwareChecksum"))) { - if(! $entry->get_value("gotoHardwareChecksum") eq $gotoHardwareChecksum) { + if (defined($entry->get_value("gotoHardwareChecksum"))) { + if (! $entry->get_value("gotoHardwareChecksum") eq $gotoHardwareChecksum) { $entry->replace(gotoHardwareChecksum => $gotoHardwareChecksum); - if($entry->update($ldap)) { - &main::daemon_log("Hardware changed! Detection triggered.", 4); + if($entry->update($ldap_handle)) { + &main::daemon_log("$session_id INFO: Hardware changed! Detection triggered.", 5); } } else { # Nothing to do return; } - } + } } - # need to fill it to LDAP - #$entry->add(gotoHardwareChecksum => $gotoHardwareChecksum); - #if($entry->update($ldap)) { - # &main::daemon_log("gotoHardwareChecksum $gotoHardwareChecksum was added to LDAP", 4); - #} - - ## Look if there another host with this checksum to use the hardware config - #$mesg = $ldap->search( - # base => $ldap_base, - # scope => 'sub', - # filter => "(&(objectClass=GOhard)(gotoHardwareChecksum=$gotoHardwareChecksum))" - #); - - #if($mesg->count>1) { - # my $clone_entry= $mesg->entry(0); - # $entry->changetype("modify"); - # foreach my $attribute ( - # "gotoSndModule", "ghNetNic", "gotoXResolution", "ghSoundAdapter", "ghCpuType", "gotoXkbModel", - # "ghGfxAdapter", "gotoXMousePort", "ghMemSize", "gotoXMouseType", "ghUsbSupport", "gotoXHsync", - # "gotoXDriver", "gotoXVsync", "gotoXMonitor") { - # my $value= $clone_entry->get_value($attribute); - # if(defined($value)) { - # if(defined($entry->get_value($attribute))) { - # $entry->delete($attribute); - # } - # &main::daemon_log("Adding attribute $attribute with value $value",1); - # $entry->add($attribute => $value); - # } - # } - # foreach my $attribute ( - # "gotoModules", "ghScsiDev", "ghIdeDev") { - # my $array= $clone_entry->get_value($attribute, 'as_ref' => 1); - # if(defined($array)) { - # if(defined($entry->get_value($attribute))) { - # $entry->delete($attribute); - # } - # foreach my $array_entry (@{$array}) { - # $entry->add($attribute => $array_entry); - # } - # } - - # } - # if($entry->update($ldap)) { - # &main::daemon_log("Added Hardware configuration to LDAP", 4); - # } - - #} - # Assemble data package my %data = (); @@ -984,13 +911,8 @@ sub hardware_config { $data{'goto_secret'}= $goto_secret; } - # Unbind - $mesg = $ldap->unbind; - - &main::daemon_log("Send detect_hardware message to $address", 4); - # Send information - return send_msg("detect_hardware", $server_address, $address, \%data); + return &build_msg("detect_hardware", $server_address, $address, \%data); } sub server_matches { @@ -1000,6 +922,8 @@ sub server_matches { if($server_ip eq $target_ip) { $result= 1; + } elsif ($target_ip eq "0.0.0.0") { + $result= 1; } elsif ($server_ip eq "0.0.0.0") { if ($target_ip eq "127.0.0.1") { $result= 1; @@ -1038,56 +962,4 @@ sub server_matches { return $result; } - -#=== FUNCTION ================================================================ -# NAME: execute_actions -# PARAMETERS: msg_hash - hash - hash from function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: invokes the script specified in msg_hash which is located under -# /etc/gosad/actions -#=============================================================================== -sub execute_actions { - my ($msg_hash) = @_ ; - my $configdir= '/etc/gosad/actions/'; - my $result; - - my $header = @{$msg_hash->{header}}[0]; - my $source = @{$msg_hash->{source}}[0]; - my $target = @{$msg_hash->{target}}[0]; - - if((not defined $source) - && (not defined $target) - && (not defined $header)) { - &main::daemon_log("ERROR: Entries missing in XML msg for gosad actions under /etc/gosad/actions"); - } else { - my $parameters=""; - my @params = @{$msg_hash->{$header}}; - my $params = join(", ", @params); - &main::daemon_log("execute_actions: got parameters: $params", 5); - - if (@params) { - foreach my $param (@params) { - my $param_value = (&get_content_from_xml_hash($msg_hash, $param))[0]; - &main::daemon_log("execute_actions: parameter -> value: $param -> $param_value", 7); - $parameters.= " ".$param_value; - } - } - - my $cmd= $configdir.$header."$parameters"; - &main::daemon_log("execute_actions: executing cmd: $cmd", 7); - $result= ""; - open(PIPE, "$cmd 2>&1 |"); - while() { - $result.=$_; - } - close(PIPE); - } - - # process the event result - - - return; -} - - 1;