#!/usr/bin/perl -Tw # # LMS version 1.9-cvs # # Copyright (C) 2001-2006 LMS Developers # # Please, see the doc/AUTHORS for more information about authors! # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License Version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, # USA. # # $Id: lms-makehosts,v 1.15 2006/01/16 09:31:50 alec Exp $ use strict; use DBI; use Config::IniFiles; use Getopt::Long; use vars qw($configfile $quiet $help $version); my $_version = '1.9-cvs'; my %options = ( "--config-file|C=s" => \$configfile, "--quiet|q" => \$quiet, "--help|h" => \$help, "--version|v" => \$version ); Getopt::Long::config("no_ignore_case"); GetOptions(%options); sub mask2prefix($) { my $mask = shift @_; my @tmp = split('\.',$mask,4); my $q = sprintf("%b%b%b%b",$tmp[0],$tmp[1],$tmp[2],$tmp[3]); $q =~ s/0*$//; if ($q =~ /0/) { print " You idiot. error in mask\n"; } my $len = length($q) ; return $len; } sub matchip($$$) { my ($ip,$net,$mask) = @_; my $prefix = mask2prefix($mask); my $bmask = 2**32 - 2**(32-$prefix); my @net = split('\.',$net,4); my $bnet = dotquad2u32($net); if(($bnet & $bmask)!= $bnet) { print "EEediot net &mask != net\n"; return 1==0 } my $bip = dotquad2u32($ip); return (($bip&$bmask) == $bnet); } sub dotquad2u32($) { my $dq = shift||'0.0.0.0'; my @dq = split('\.',$dq,4); return ((($dq[0] << 8) + $dq[1] << 8) + $dq[2] << 8) + $dq[3]; } sub u32todotquad($) { my $p = shift @_; return sprintf "%d.%d.%d.%d", ($p>>24)&0xff,($p>>16)&0xff, ($p>>8)&0xff,$p&0xff; } if($help) { print STDERR < $configfile; print @Config::IniFiles::errors; my $cfile = $ini->val('hosts', 'config_file') || '/etc/hosts'; my $cuid = $ini->val('hosts','config_owneruid') || 0; my $cgid = $ini->val('hosts','config_ownergid') || 0; my $cperm = $ini->val('hosts','config_permission') || '0644'; my $cheader = $ini->val('hosts','config_header') || '127.0.0.1 localhost localhost.localdomain'; my $networks_list = $ini->val('hosts','networks') || ''; my $customergroups_list = $ini->val('hosts','customergroups') || ''; my $dbtype = $ini->val('database', 'type') || 'mysql'; my $dbhost = $ini->val('database', 'host') || 'localhost'; my $dbuser = $ini->val('database', 'user') || 'root'; my $dbpasswd = $ini->val('database', 'password') || ''; my $dbname = $ini->val('database', 'database') || 'lms'; my $dbase; if($dbtype eq "mysql") { $dbase = DBI->connect("DBI:mysql:database=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 }); } elsif($dbtype eq "postgres") { $dbase = DBI->connect("DBI:Pg:dbname=$dbname;host=$dbhost","$dbuser","$dbpasswd", { RaiseError => 1 }); } else { print STDERR "Fatal error: unsupported database type: $dbtype, exiting.\n"; exit 1; } open(HOSTSFILE, ">$cfile") or die("Fatal error: Unable to write $cfile, exiting.\n"); print HOSTSFILE $cheader."\n"; if(!$networks_list) { my $dbq = $dbase->prepare("SELECT name FROM networks"); $dbq->execute(); while (my $row = $dbq->fetchrow_hashref()) { $networks_list = "$networks_list $row->{'name'}"; } $dbq->finish(); } my @networks = split ' ', $networks_list; my $inicustomergroups = $customergroups_list; if(!$customergroups_list) { my $dbq = $dbase->prepare("SELECT name FROM customergroups"); $dbq->execute(); while (my $row = $dbq->fetchrow_hashref()) { $customergroups_list = "$customergroups_list $row->{'name'}"; } $dbq->finish(); } my %customergrouplist; my $dbq = $dbase->prepare("SELECT id, name FROM customergroups"); $dbq->execute(); while (my $row = $dbq->fetchrow_hashref()) { $customergrouplist{$row->{'name'}} = $row->{'id'}; } $dbq->finish(); my @customergroups = split ' ',$customergroups_list; $dbq = $dbase->prepare("SELECT name, ipaddr, ownerid FROM nodes"); $dbq->execute(); my %namelist; my %ownerlist; while (my $row = $dbq->fetchrow_hashref()) { $namelist{u32todotquad($row->{'ipaddr'})} = lc($row->{'name'}); $ownerlist{u32todotquad($row->{'ipaddr'})} = $row->{'ownerid'}; } $dbq->finish(); foreach my $key (@networks) { my $dbq = $dbase->prepare("SELECT address, mask FROM networks WHERE name = UPPER('$key')"); $dbq->execute(); while (my $row = $dbq->fetchrow_hashref()) { my $longip = $row->{'address'}; my $netsize = 2**(32 - mask2prefix($row->{'mask'})); for(my $i = $longip; $i < $longip + $netsize; $i++) { my $ipaddr = u32todotquad($i); if ($namelist{$ipaddr}) { my $customergroupscount = 0; foreach my $key2 (@customergroups) { my $sdbq = $dbase->prepare("SELECT count(customerid) AS total FROM customerassignments WHERE customerid=".$ownerlist{$ipaddr}." AND customergroupid=".$customergrouplist{$key2}); $sdbq->execute(); my $srow = $sdbq->fetchrow_hashref(); if ($srow->{'total'} eq 1) { $customergroupscount++; } $sdbq->finish(); } if($customergroupscount || !$inicustomergroups) { print HOSTSFILE "$ipaddr\t$namelist{$ipaddr}\n"; } } } } $dbq->finish(); } $dbase->disconnect(); close(HOSTSFILE); chown $cuid, $cgid, $cfile or print "Warning! Unable to set owner of $cfile to $cuid.$cgid.\n"; chmod oct($cperm), $cfile or print "Warning! Unable to set permission $cperm to $cfile.\n";