#! /usr/bin/perl -w
# @(#)dyn_update2.pl
# Author: Sebastien Tanguy <seb+scripts@death-gate.fr.eu.org>
# Version: $Id: dyn_update2.pl,v 0.0 2002/11/17 18:13:33 seb Exp $


use Net::DNS;

my $DNSSERVER = "127.0.0.1";
# my $DNSSERVER = "192.168.100.51";
my $DEFAULTDOMAIN = "shebang.fdns.net";

sub set_name 
{
    my( $name, $domain, $ip ) = @_;
    my $fullname;

    if ( $name ) {
        $fullname = $name . "." . $domain ;
    } else {
        $fullname = $domain;
    }

    my $res = new Net::DNS::Resolver;
    
    my $query = $res->search( $fullname );
    my $update = new Net::DNS::Update( $domain );
      
    if ( $query ) {
        # Bon, on a déjà qqchose.
        
        # il faut au moins un A.
        $update->push( "update", 
                       new Net::DNS::RR( Name => $fullname,
                                         Type => 'A',
                                         Ttl => 0,
                                         Class => "ANY",
                                         Rdata => "" )
                     );
#        $res = new Net::DNS::Resolver;
        $res->nameservers( $DNSSERVER );
        my $reply = $res->send( $update );

        if ( defined $reply and 
             ( $reply->header->rcode eq "NOERROR" ) ) {
            # suppression OK !
        } else {
            if ( defined $reply ) {
                print $reply->header->rcode,"\n";
            }
            print $res->errorstring,"\n";
            # Erk !
            return 1;
        }
        $update = new Net::DNS::Update( $domain );
    } else {
    }
    
    # NXRRSET - Prerequisite is that no A records exist for the name.
    $update->push("pre", new Net::DNS::RR( Name  => $fullname,
                                           Class => "NONE",
                                           Type  => "A"));

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

    my $reply = $res->send($update);
    
    if ( defined $reply and ( $reply->header->rcode eq "NOERROR" ) ) {
        # OK !
    } else {
        # Erk (3) !
        return 1;
    }
    return 0;
}



my $ligne = <STDIN> ;
chomp $ligne;

my( $auth, $nom, $domaine, $ip );

while ( defined($ligne) and $ligne) {

    ## Ajouter une vérification d'authentification quelconque ici

    # Sujet du type: set {nom} as {ip} in {domaine}
    if ( $ligne =~ /^Subject:\s*set\s+([\w.]*)\s+as\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*(in\s+([\w.]{1,35}))?$/ ) {

        $nom = $1;
        $ip = $2 ;
        if ( defined $4 ) {
            $domaine = $4;
        } else {
            $domaine = $DEFAULTDOMAIN;
        }

    }
    
    $ligne = <STDIN>;
    chomp $ligne;
}

if ( not valid_auth( $auth ) ) {
    log_and_exit( "Authentification inconnue", 1);
}
if ( not $nom or not $ip or not $domaine ) {
    log_and_exit( "Paramètres non définis", 1);
}

if ( $nom eq '.' ) {
    $nom = "";
}

$res = set_name( $nom, $domaine, $ip );

if ( $res == 1) {
    log_and_exit( "Erreur lors de la mise de $nom.$domaine à $ip", 1 );
} else {
    log_and_exit( "$nom.$domaine mis à $ip", 0 );
}

sub valid_auth
{
    my $auth = shift ;
    ##TODO: Valider l'authentification préalable
    return 1;
}
use Sys::Syslog;

sub log_and_exit
{
    my( $phrase, $val ) = @_ ;
    openlog( "dyn_update", "cons,pid", "authpriv" );
    syslog( "warning", $phrase );
    closelog();
    exit( $val );
}
