#!/usr/bin/perl # TODO: Accept supernat ip/port and sessionId in lieu of Toolbox object package Pos::Webtop::Wins; use strict; use Pos::db; use Net::DNS::Resolver; use Pos::Webtop::Toolbox; =head1 NAME Pos::Webtop::Wins -- API for WINS resolution via nmblookup =head1 USAGE my $dottedQuadIp = Pos::Webtop::Wins::resolveHost( db => $db, userId => 16, host => 'exchange', toolBox => $toolBox ); =head1 SYNOPSIS Pos::Webtop::Wins::resolveHost() will lookup the WINS servers for the specified userId in the application database (populated by the 'WINS server' policy). It then executes nmblookup, nmblookup -U -s /dev/null -R 'exchange' parses the output, and returns the resulting IP address (or undef if none is found). It will attempt to contact all WINS servers in the database for this user. WINS server settings are retrieved from the 'client_wins_server' table. If you set the param webSessionNat to a false value (0), the nat used for the wins servers will be removed when done and not associated with the client object in the toolbox (web session id). If you set this to false you will also have to make sure that the db object you send in is a WRITER db object since releaseing the natted ip writes to the db object that supernat watches on. TODO: The path to nmblookup should be set by Pos::defaults::getNmblookupPath() =cut sub resolveHost { my ($db, $userId, $host, $toolBox, $webSessionNat) = @{{@_}}{qw/db userId host toolBox webSessionNat/}; $webSessionNat = 1 unless defined $webSessionNat; if ( not defined $toolBox ) { warn "Pos::Webtop::Wins::resolveHost(): Right now, a Toolbox object must be passed and I did not get one; returning undef"; return undef; } my $client = $toolBox->getClient(); my $customerId = $client->getCustomerId(); # We don't need the path; this fixes taint-checking problems delete $ENV{'PATH'}; if ( $host =~ /^([\w\.\-]+)$/ ) { $host = $1; } else { warn "Pos::Webtop::Wins::resolveHost(): Host contained invalid characters; returning undef"; return undef; } # TODO: Check parameters passed my @winsServerIps = $db->query( sql => " SELECT RAWIP32_TO_DOTTED_QUAD(wins_server_ip) FROM client_wins_server WHERE user_id = '$userId' "); if ( !@winsServerIps) { warn "Pos::Webtop::Wins::resolveHost(): No WINS servers for user '$userId'; returning undef"; return undef; } # Attempt to resolve the host with each WINS server in the db my $hostIp; foreach my $winsServerIp (@winsServerIps) { my $supernattedWinsServerIp; #if ( $ENV{'SERVER_NAME'} eq 'dev.positivenetworks.net' or $ENV{'SERVER_NAME'} =~ /stage/ ) if ( $ENV{'SERVER_NAME'} eq 'dev.positivenetworks.net') { $supernattedWinsServerIp = $winsServerIp; } else { if ( $webSessionNat ) { # Do a supernat lookup to get the internal supernat IP for this server $supernattedWinsServerIp = $toolBox->getSupernattedIp( host => $winsServerIp ); } else { # get internal supernat ip with a dynamic backend nat $supernattedWinsServerIp = $toolBox->getSupernatInternalAddress( webSessionNat=> 0, ip=> $winsServerIp ); } } if ( not defined $supernattedWinsServerIp ) { warn "Pos::Webtop::Wins::resolveHost(): Couldn't get supernatted IP for WINS server '$winsServerIp'; returning undef"; return undef; } # Just to be sure... (and to satisfy -T) $host =~ s/[^\w\.\-]//g; $supernattedWinsServerIp =~ s/[^\d\.]//g; if ( $supernattedWinsServerIp =~ /^((?:\d+\.){3}\d+)$/ ) { $supernattedWinsServerIp = $1; } else { warn "Pos::Webtop::Wins::resolveHost(): Got invalid WINS server IP from database after supernat request: '$supernattedWinsServerIp'; returning undef"; return undef; } my @nmblookup = `/usr/bin/nmblookup -U $supernattedWinsServerIp -s /dev/null -R '$host'`; if ( not $webSessionNat ) { Pos::Webtop::Supernat::supernatReleaseDynamicBackendNat( db=> $db, companyId=> $customerId, actualAddress=> $winsServerIp ); } # Sample output from nmblookup: # # querying data on 209.242.113.79 # 209.242.113.79 data<00> chomp $nmblookup[1]; if ( $nmblookup[1] =~ /^((?:\d+\.){3}\d+)\s(?:[^\s]+)<00>$/ ) { $hostIp = $1; last; } elsif ($nmblookup[1] =~ /fail/ ) { warn "Pos::Webtop::Wins::resolveHost(): WINS query failed for host '$host' to server '$supernattedWinsServerIp'"; } else { warn "Pos::Webtop::Wins::resolveHost(): Unknown results from WINS query for host '$host' to server '$supernattedWinsServerIp':\n@nmblookup"; } next; } return $hostIp; } 1;