bin/update: Check that the hostname is actually plausibly formed.
[dyndns] / bin / update
1 #! /bin/sh
2
3 set -e
4 . ./dyndns.conf
5
6 ## Check that the environment is set up properly.
7 for i in DYNDNS_ZONE DYNDNS_HOST DYNDNS_SERVER DYNDNS_KEY SSH_CLIENT; do
8 eval havep=\${$i+t}\${$i-nil}
9 case $havep in nil) echo >&2 "$0: variable $i unset"; exit 2 ;; esac
10 done
11
12 ## Find the client address. This may be useful.
13 set -- $SSH_CLIENT; client=$1
14
15 ## Parse the commad line.
16 set -- $SSH_ORIGINAL_COMMAND
17
18 fail_usage () {
19 cat >&2 <<EOF
20 usage: $0 COMMAND ARGS...
21
22 Commands:
23 set [-force] HOST [ADDR]
24 unset HOST
25 EOF
26 exit 1
27 }
28 getarg='case $# in 0) fail_usage ;; esac; arg=$1; shift'
29 doneargs='case $# in 0) ;; *) fail_usage ;; esac'
30
31 checkhost () {
32 host=$1
33
34 case "$host" in
35 *..* | .* | *. | *[!-_.a-zA-Z0-9]*)
36 echo >&2 "$0: invalid hostname"
37 exit 2
38 ;;
39 esac
40
41 matchp=nil
42 for pat in $DYNDNS_HOST; do
43 case "$host" in $pat) matchp=t ;; esac
44 done
45 case $matchp in nil) echo >&2 "$0: hostname not permitted"; exit 2 ;; esac
46 }
47
48 doupdate () {
49 cmd=$1
50
51 nsupdate -k "$DYNDNS_KEY" <<EOF
52 server $DYNDNS_SERVER
53 zone $DYNDNS_ZONE
54 $cmd
55 send
56 EOF
57 }
58
59 eval $getarg; cmd=$arg
60 case "$cmd" in
61 set)
62 forcep=nil
63 eval $getarg
64 case "$arg" in -force) forcep=t; eval $getarg ;; esac
65 host=$arg
66 case "$#,$forcep,$1" in
67 0,nil,*) addr=$client ;;
68 0,t,*) fail_usage ;;
69 *,nil,"$client" | *,t,*) addr=$1; shift ;;
70 *)
71 echo >&2 "$0: incorrect address (wanted = $2; found = $addr)"
72 exit 3
73 ;;
74 esac
75 eval $doneargs
76 checkhost "$host"
77 case $addr in
78 *:*) rrtype=AAAA ;;
79 *.*) rrtype=A ;;
80 *) echo >&2 "$0: failed to parse new address"; exit 2 ;;
81 esac
82 name=$host.$DYNDNS_ZONE
83 doupdate "
84 update delete $name IN $rrtype
85 update add $name ${DYNDNS_TTL-14400} IN $rrtype $addr"
86 ;;
87 unset)
88 eval $getarg; host=$arg
89 eval $doneargs
90 checkhost "$host"
91 name=$host.$DYNDNS_ZONE
92 doupdate "update delete $name IN"
93 ;;
94 *)
95 fail_usage
96 ;;
97 esac