#!/usr/bin/perl
######################################################################
#
# dynname -- Add or Remove a dynamic dns name for the authenticated
#            http user.
#
# Written by David Simmons, July 1997.
# This script is in the public domain.
#
######################################################################

######################################################################
# Site-specific variabels
######################################################################
$title_html = "Title goes here<br><hr>";
$zone = "dyn.company.com";
######################################################################
# Main function code
######################################################################

use CGI;
use Net::DNS;

$query = new CGI;
print $query->header();

#
# determine the ip address
#

$ipaddress = $query->remote_addr();

#
# determine the authenticated user
#

$authuser = $ENV{'REMOTE_USER'};

#
# print html beginnings...
#
print <<'_EOM_'
<html><head>
<title>Dynamic DNS results</title>
</head>
<body>
_EOM_
    ;
print "$title_html\n";

print <<'_EOM_'
<p>
<h1>DNS update in progress...</h1>
_EOM_
    ;

#
# take action base on the parameters
#
if (! $query->param('func')) {
	print "<b>Error: please specify \"set\" or \"remove\".</b>\n";
} else {
    $func = $query->param('func');

    #
    # Process functions
    #

    if ($func eq 'set') {
	&set_name;
    } elsif ($func eq 'remove') {
	&remove_name;
    } else {
	print "<b>Unknown function: $func</b>";
    }
}

######################################################################
# Subroutines
######################################################################

sub set_name {
    local $name = $authuser . '.' . $zone;

    #
    # If there is already an A record for this name, remove it.
    #

    $res = new Net::DNS::Resolver;
    $query = $res->search($name);
    if ($query) {
	print "Attempting to remove old entry: $name = ";
	foreach $rr ($query->answer) {
	    next unless $rr->type eq "A";
	    print $rr->address, " ";
	}
	print "<br>";
	$update = new Net::DNS::Update($zone);

	# Prerequisite (assumed) is that an A record must already exist.
	$update->push("update",
		      $b = new Net::DNS::RR(Name    => $name,
					    Type    => "A",
					    Ttl     => 0,
					    Class   => "ANY",
					    Rdata   => ""));

	$res = new Net::DNS::Resolver;
	$res->nameservers("127.0.0.1");
	$ans = $res->send($update);

	if (defined $ans) {
	    print "Return code: ", $ans->header->rcode, "<br>\n";
	    if ($ans->header->rcode eq "NOERROR") {
		print "Old entry removed successfully.<br>\n";
	    } else {
		print "<b>Failed to remove old data!!!</b><br>\n";
	    }
	} else {
	    print "Error: $res->errorstring <br>\n";
	    print "<b>Failed to remove old data!!!!</b><br>\n";
	}
    }

    print "adding \"$name\" to zone \"$zone\".<br>\n";
    $update = new Net::DNS::Update($zone);
    # NXRRSET - Prerequisite is that no A records exist for the name.
    $update->push("pre", new Net::DNS::RR(Name  => $name,
					  Class => "NONE",
					  Type  => "A"));

    # Add one A records for the name.
    $update->push("update", new Net::DNS::RR(Name    => $name,
					     Ttl     => 10,
					     Type    => "A",
					     Address => $ipaddress));

    $res = new Net::DNS::Resolver;
    $res->nameservers("127.0.0.1");
    $ans = $res->send($update);

    if (defined $ans) {
	print "Return code: ", $ans->header->rcode, "<p>\n";
	if ($ans->header->rcode eq "NOERROR") {
	    print "<b>Success!</b><p>\n";
	} else {
	    print "<b>Failure!</b><p>\n";
	}
    } else {
	print "Error: $res->errorstring <p>\n";
	print "<b>Failure!</b><p>\n";
    }
}

sub remove_name {
    local $name = $authuser . '.' . $zone;
    print "removing \"$name\" from zone \"$zone\".<br>\n";
    $update = new Net::DNS::Update($zone);

    # Prerequisite is that an A record must already exist.

    $update->push("update",
		  $b = new Net::DNS::RR(Name    => $name,
					Type    => "A",
					Ttl     => 0,
					Class   => "ANY",
					Rdata   => ""));

    $res = new Net::DNS::Resolver;
    $res->nameservers("127.0.0.1");
    $ans = $res->send($update);

    if (defined $ans) {
	print "Return code: ", $ans->header->rcode, "<p>\n";
	if ($ans->header->rcode eq "NOERROR") {
	    print "<b>Success!</b><p>\n";
	} else {
	    print "<b>Failure!</b><p>\n";
	}
    } else {
	print "Error: $res->errorstring <p>\n";
	print "<b>Failure!</b><p>\n";
    }
}

