Project

General

Profile

1
#!/usr/bin/perl
2

    
3
# manage-domain.pl -- Manage a domain using DDNS to add or remove hosts
4
#
5
#  '$RCSfile$'
6
#  Copyright: 2005 Regents of the University of California 
7
#
8
#   '$Author: jones $'
9
#     '$Date: 2005-10-13 15:43:22 -0700 (Thu, 13 Oct 2005) $'
10
# '$Revision: 2674 $' 
11
#
12
#  This program is free software; you can redistribute it and/or modify
13
#  it under the terms of the GNU General Public License as published by
14
#  the Free Software Foundation; either version 2 of the License, or
15
#  (at your option) any later version.
16
#
17
#  This program is distributed in the hope that it will be useful,
18
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
#  GNU General Public License for more details.
21
#
22
#  You should have received a copy of the GNU General Public License
23
#  along with this program; if not, write to the Free Software
24
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25
#
26

    
27
use Net::DNS;
28
use Getopt::Long;
29
use strict;
30

    
31
# include the configuration
32
require '/etc/control-services.conf';
33

    
34
# make my pipes piping hot
35
$| = 1;
36

    
37
# run the main routine
38
&main;
39

    
40
sub main {
41
    my ($host, $ip, $command);
42

    
43
    GetOptions( "host=s" => \$host,
44
                "ip=s"   => \$ip,
45
                "command=s"   => \$command );
46
    if (! defined($host) || ! defined ($ip) || !defined($command)) {
47
        usage();
48
    } else {
49
        my $zone = $main::zones[0];
50
        my $class = $main::classes[0];
51
        my $ttl = '60';
52
        my $type = 'A';
53
        my $message = '';
54
        my $success = 1;
55

    
56
        # get a resolver handle and set the dns server to use
57
        my $resref = &get_resolver($main::tsig_keyname,$main::tsig_key);
58
        $$resref->nameservers($main::nameservers[0]);
59

    
60
        if ($command eq 'add') {
61
            # Add a record
62
            ($success,$message) = &add_records( $resref, $zone, $class,
63
                                        $host, $ttl, $type, $ip );
64
            debug("Add records success: " . $success);
65
            debug("Add records message: " . $message);
66
        } elsif ($command eq 'delete') {
67
            # Delete a record
68
            my $record = "$host.$zone $type $ip";
69
            #my $record = "$host.$zone";
70
            my @rr = ($record);
71
            ($success,$message) = &del_records($resref,$zone,$class,@rr);
72
            debug("Del records success: " . $success);
73
            debug("Del records message: " . $message);
74
        } else {
75
            usage();
76
        }
77
    }
78
}
79

    
80
# Get a resolver to be used for DDNS updates
81
sub get_resolver {
82
    my ($tsig_keyname,$tsig_key) = @_;
83
    my $res = Net::DNS::Resolver->new;
84
    $res->tsig($tsig_keyname,$tsig_key);
85
    return \$res;
86
}
87

    
88
# Add a RR using DDNS update
89
sub add_records {
90
    my ($res,$zone,$class,$name,$ttl,$type,$content) = @_;
91
    
92
    # create update packet
93
    my $update = Net::DNS::Update->new($zone,$class);
94
    my $rr = "$name.$zone $ttl $type $content";
95
    debug("Inserting new record: \n    " . $rr);
96
    $update->push(update => rr_add($rr));
97
    my $reply = ${$res}->send($update);
98

    
99
    # initialize return vars
100
    my $success = 0;
101
    my $message = '';
102

    
103
    # Did it work?
104
    if ($reply) {
105
    if ($reply->header->rcode eq 'NOERROR') {
106
            $message = "Update succeeded";
107
        $success = 1;
108
        } else {
109
            $message = 'Update failed: ' . $reply->header->rcode;
110
        }
111
    } else {
112
        $message = 'Update failed: ' . $res->errorstring;
113
    }
114

    
115
    return ($success,$message);
116
}
117

    
118
# Delete one or more RRs using DDNS update
119
sub del_records {
120
    my ($res,$zone,$class,@rr) = @_;
121

    
122
    my $update = Net::DNS::Update->new($zone,$class);
123

    
124
    # build update packet(s)
125
    foreach my $record (@rr) {
126
        $update->push(update => rr_del($record));
127
    }
128

    
129
    # send it
130
    my $reply = ${$res}->send($update);
131

    
132
    my $msg = '';
133
    my $success = 0;
134
    if ($reply) {
135
        if ($reply->header->rcode eq 'NOERROR') {
136
            $msg = "Update succeeded";
137
        $success = 1;
138
        } else {
139
            $msg = 'Update failed: ' . $reply->header->rcode;
140
        $success = 0;
141
        }
142
    } else {
143
        $msg = 'Update failed: ' . $res->errorstring;
144
    $success = 0;
145
    }
146
    return ($success,$msg);
147
}
148

    
149
# Print out debugging messages
150
sub debug {
151
    my $msg = shift;
152
    print $msg, "\n";
153
}
154

    
155
# Print a usage statement
156
sub usage {
157
        print "Usage: manage-domain.pl --host hostname --ip xxx.xxx.xxx.xxx --command [add|delete]\n";
158
}
(4-4/4)