source: branches/stable/dns-rpc.cgi@ 464

Last change on this file since 464 was 263, checked in by Kris Deugau, 13 years ago

/branches/stable

Merge /trunk r262 forward for release. Merge was clean.

  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author Id
File size: 11.2 KB
Line 
1#!/usr/bin/perl -w -T
2# XMLRPC interface to manipulate most DNS DB entities
3##
4# $Id: dns-rpc.cgi 263 2012-03-04 22:57:34Z kdeugau $
5# Copyright 2011 Kris Deugau <kdeugau@deepnet.cx>
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19##
20
21use strict;
22use warnings;
23
24# don't remove! required for GNU/FHS-ish install from tarball
25use lib '.'; ##uselib##
26
27use DNSDB; # note we're not importing subs; this lets us (ab)use the same sub names here for convenience
28use Data::Dumper;
29
30#use Frontier::RPC2;
31use Frontier::Responder;
32
33## We need to handle a couple of things globally, rather than pasting the same bit into *every* sub.
34## So, let's subclass Frontier::RPC2 + Frontier::Responder, so we can override the single sub in each
35## that needs kicking
36#### hmm. put this in a separate file?
37#package DNSDB::RPC;
38#our @ISA = ("Frontier::RPC2", "Frontier::Responder");
39#package main;
40
41loadConfig();
42
43# need to create a DNSDB object too
44my ($dbh,$msg) = DNSDB::connectDB($DNSDB::config{dbname}, $DNSDB::config{dbuser},
45 $DNSDB::config{dbpass}, $DNSDB::config{dbhost});
46
47DNSDB::initGlobals($dbh);
48
49my $methods = {
50 'dnsdb.addDomain' => \&addDomain,
51 'dnsdb.delDomain' => \&delDomain,
52 'dnsdb.addGroup' => \&addGroup,
53 'dnsdb.delGroup' => \&delGroup,
54 'dnsdb.addUser' => \&addUser,
55 'dnsdb.updateUser' => \&updateUser,
56 'dnsdb.delUser' => \&delUser,
57 'dnsdb.getSOA' => \&getSOA,
58 'dnsdb.getRecLine' => \&getRecLine,
59 'dnsdb.getDomRecs' => \&getDomRecs,
60 'dnsdb.getRecCount' => \&getRecCount,
61 'dnsdb.addRec' => \&addRec,
62 'dnsdb.delRec' => \&delRec,
63 'dnsdb.domStatus' => \&domStatus,
64
65 'dnsdb.getMethods' => \&get_method_list
66};
67
68my $res = Frontier::Responder->new(
69 methods => $methods
70 );
71
72# "Can't do that" errors
73##fixme: this MUST be loaded from a config file! Also must support multiple IPs
74if ($ENV{REMOTE_ADDR} ne '192.168.2.116') {
75 print "Content-type: text/xml\n\n".$res->{_decode}->encode_fault(5, "Access denied");
76 exit;
77}
78if (!$dbh) {
79 print "Content-type: text/xml\n\n".$res->{_decode}->encode_fault(5, $msg);
80 exit;
81}
82##fixme: fail on missing rpcuser/rpcsystem args
83
84print $res->answer;
85
86exit;
87
88##
89## Subs below here
90##
91
92#sub connectDB {
93#sub finish {
94#sub initGlobals {
95#sub initPermissions {
96#sub getPermissions {
97#sub changePermissions {
98#sub comparePermissions {
99#sub changeGroup {
100#sub _log {
101
102sub addDomain {
103 my %args = @_;
104
105 # Make sure we've got all the local bits we need
106 die "Missing remote username" if !$args{rpcuser}; # for logging
107 die "Missing remote system name" if !$args{rpcsystem}; # for logging
108
109 my ($code, $msg) = DNSDB::addDomain($dbh, $args{domain}, $args{group}, $args{state});
110 die $msg if $code eq 'FAIL';
111 return $msg; # domain ID
112}
113
114sub delDomain {
115 my %args = @_;
116
117 # Make sure we've got all the local bits we need
118 die "Missing remote username" if !$args{rpcuser}; # for logging
119 die "Missing remote system name" if !$args{rpcsystem}; # for logging
120
121 my ($code,$msg);
122 # Let's be nice; delete based on domid OR domain name. Saves an RPC call round-trip, maybe.
123 if ($args{domain} =~ /^\d+$/) {
124 ($code,$msg) = DNSDB::delDomain($dbh, $args{domain});
125 } else {
126 my $domid = DNSDB::domainID($dbh, $args{domain});
127 die "Can't find domain" if !$domid;
128 ($code,$msg) = DNSDB::delDomain($dbh, $domid);
129 }
130 die $msg if $code eq 'FAIL';
131}
132
133#sub domainName {
134#sub domainID {
135
136sub addGroup {
137 my %args = @_;
138
139 # Make sure we've got all the local bits we need
140 die "Missing remote username" if !$args{rpcuser}; # for logging
141 die "Missing remote system name" if !$args{rpcsystem}; # for logging
142
143# not sure how to usefully represent permissions from any further out from DNSDB.pm :/
144# not to mention, permissions are checked at the UI layer, not the DB layer.
145 my $perms = {domain_edit => 1, domain_create => 1, domain_delete => 1,
146 record_edit => 1, record_create => 1, record_delete => 1
147 };
148## optional $inhert arg?
149 my ($code,$msg) = DNSDB::addGroup($dbh, $args{groupname}, $args{parent_id}, $perms);
150 die $msg if $code eq 'FAIL';
151 return $msg;
152}
153
154sub delGroup {
155 my %args = @_;
156
157 # Make sure we've got all the local bits we need
158 die "Missing remote username" if !$args{rpcuser}; # for logging
159 die "Missing remote system name" if !$args{rpcsystem}; # for logging
160
161 my ($code,$msg);
162 # Let's be nice; delete based on groupid OR group name. Saves an RPC call round-trip, maybe.
163 if ($args{group} =~ /^\d+$/) {
164 ($code,$msg) = DNSDB::delGroup($dbh, $args{group});
165 } else {
166 my $grpid = DNSDB::groupID($dbh, $args{group});
167 die "Can't find group" if !$grpid;
168 ($code,$msg) = DNSDB::delGroup($dbh, $grpid);
169 }
170 die $msg if $code eq 'FAIL';
171}
172
173#sub getChildren {
174#sub groupName {
175#sub groupID {
176
177sub addUser {
178 my %args = @_;
179
180 # Make sure we've got all the local bits we need
181 die "Missing remote username" if !$args{rpcuser}; # for logging
182 die "Missing remote system name" if !$args{rpcsystem}; # for logging
183
184# not sure how to usefully represent permissions from any further out from DNSDB.pm :/
185# not to mention, permissions are checked at the UI layer, not the DB layer.
186 my $perms = {domain_edit => 1, domain_create => 1, domain_delete => 1,
187 record_edit => 1, record_create => 1, record_delete => 1
188 };
189 # bend and twist; get those arguments in in the right order!
190 $args{type} = 'u' if !$args{type};
191 $args{permstring} = 'i' if !defined($args{permstring});
192 my @userargs = ($args{username}, $args{group}, $args{pass}, $args{state}, $args{type}, $args{permstring});
193 for my $argname ('fname','lname','phone') {
194 last if !$args{$argname};
195 push @userargs, $args{$argname};
196 }
197 my ($code,$msg) = DNSDB::addUser($dbh, @userargs);
198 die $msg if $code eq 'FAIL';
199 return $msg;
200}
201
202#sub checkUser {
203
204sub updateUser {
205 my %args = @_;
206
207 # Make sure we've got all the local bits we need
208 die "Missing remote username" if !$args{rpcuser}; # for logging
209 die "Missing remote system name" if !$args{rpcsystem}; # for logging
210
211 die "Missing UID" if !$args{uid};
212
213# not sure how to usefully represent permissions from any further out from DNSDB.pm :/
214# not to mention, permissions are checked at the UI layer, not the DB layer.
215 my $perms = {domain_edit => 1, domain_create => 1, domain_delete => 1,
216 record_edit => 1, record_create => 1, record_delete => 1
217 };
218 # bend and twist; get those arguments in in the right order!
219 my @userargs = ($args{uid}, $args{username}, $args{group}, $args{pass}, $args{state}, $args{type});
220 for my $argname ('fname','lname','phone') {
221 last if !$args{$argname};
222 push @userargs, $args{$argname};
223 }
224##fixme: also underlying in DNSDB::updateUser(): no way to just update this or that attribute;
225# have to pass them all in to be overwritten
226 my ($code,$msg) = DNSDB::addUser($dbh, @userargs);
227 die $msg if $code eq 'FAIL';
228}
229
230sub delUser {
231 my %args = @_;
232
233 # Make sure we've got all the local bits we need
234 die "Missing remote username" if !$args{rpcuser}; # for logging
235 die "Missing remote system name" if !$args{rpcsystem}; # for logging
236
237 die "Missing UID" if !$args{uid};
238 my ($code,$msg) = DNSDB::delUser($dbh, $args{uid});
239 die $msg if $code eq 'FAIL';
240}
241
242#sub userFullName {
243#sub userStatus {
244#sub getUserData {
245
246sub getSOA {
247 my %args = @_;
248
249 # Make sure we've got all the local bits we need
250 die "Missing remote username" if !$args{rpcuser}; # for logging
251 die "Missing remote system name" if !$args{rpcsystem}; # for logging
252
253 my %ret = DNSDB::getSOA($dbh, $args{def}, $args{id});
254 if (!$ret{recid}) {
255 if ($args{def} eq 'y') {
256 die "No default SOA record in group";
257 } else {
258 die "No SOA record in domain";
259 }
260 }
261 return \%ret;
262}
263
264sub getRecLine {
265 my %args = @_;
266
267 # Make sure we've got all the local bits we need
268 die "Missing remote username" if !$args{rpcuser}; # for logging
269 die "Missing remote system name" if !$args{rpcsystem}; # for logging
270
271 my $ret = DNSDB::getRecLine($dbh, $args{def}, $args{id});
272
273 die $DNSDB::errstr if !$ret;
274
275 return $ret;
276}
277
278sub getDomRecs {
279 my %args = @_;
280
281 # Make sure we've got all the local bits we need
282 die "Missing remote username" if !$args{rpcuser}; # for logging
283 die "Missing remote system name" if !$args{rpcsystem}; # for logging
284
285#bleh
286 $args{nrecs} = 'all' if !$args{nrecs};
287 $args{nstart} = 0 if !$args{nstart};
288## for order, need to map input to column names
289 $args{order} = 'host' if !$args{order};
290 $args{direction} = 'ASC' if !$args{direction};
291
292 my $ret = DNSDB::getDomRecs($dbh, $args{def}, $args{id}, $args{nrecs}, $args{nstart}, $args{order}, $args{direction});
293
294 die $DNSDB::errstr if !$ret;
295
296 return $ret;
297}
298
299sub getRecCount {
300 my %args = @_;
301
302 # Make sure we've got all the local bits we need
303 die "Missing remote username" if !$args{rpcuser}; # for logging
304 die "Missing remote system name" if !$args{rpcsystem}; # for logging
305
306 return DNSDB::getRecCount($dbh, $id);
307}
308
309sub addRec {
310 my %args = @_;
311
312 # Make sure we've got all the local bits we need
313 die "Missing remote username" if !$args{rpcuser}; # for logging
314 die "Missing remote system name" if !$args{rpcsystem}; # for logging
315
316 # note dist, weight, port are not reequired on all types; will be ignored if not needed.
317 my ($code, $msg) = DNSDB::addRec($dbh, $args{def}, $args{domid}, $args{host}, $typemap{$args{type}},
318 $args{val}, $args{ttl}, $args{dist}, $args{weight}, $args{port});
319
320 die $msg if $code eq 'FAIL';
321}
322
323sub updateRec {
324 my %args = @_;
325
326 # Make sure we've got all the local bits we need
327 die "Missing remote username" if !$args{rpcuser}; # for logging
328 die "Missing remote system name" if !$args{rpcsystem}; # for logging
329
330 # note dist, weight, port are not reequired on all types; will be ignored if not needed.
331 my ($code, $msg) = DNSDB::updateRec($dbh, $args{def}, $args{recid}, $args{host}, $typemap{$args{type}},
332 $args{val}, $args{ttl}, $args{dist}, $args{weight}, $args{port});
333
334 die $msg if $code eq 'FAIL';
335}
336
337sub delRec {
338 my %args = @_;
339
340 # Make sure we've got all the local bits we need
341 die "Missing remote username" if !$args{rpcuser}; # for logging
342 die "Missing remote system name" if !$args{rpcsystem}; # for logging
343
344 # note dist, weight, port are not reequired on all types; will be ignored if not needed.
345 my ($code, $msg) = DNSDB::delRec($dbh, $args{def}, $args{recid});
346
347 die $msg if $code eq 'FAIL';
348}
349
350#sub getParents {
351
352sub domStatus {
353 my %args = @_;
354
355 # Make sure we've got all the local bits we need
356 die "Missing remote username" if !$args{rpcuser}; # for logging
357 die "Missing remote system name" if !$args{rpcsystem}; # for logging
358
359 my @arglist = ($dbh, $args{domid});
360 push @arglist, $args{status} if defined($args{status});
361
362 my $status = DNSDB::domStatus(@arglist);
363}
364
365#sub importAXFR {
366#sub export {
367#sub __export_tiny {
368
369sub get_method_list {
370 my @methods = keys %{$methods};
371 return \@methods;
372}
Note: See TracBrowser for help on using the repository browser.