| 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 | matchp=nil |
| 35 | for pat in $DYNDNS_HOST; do |
| 36 | case "$host" in $pat) matchp=t ;; esac |
| 37 | done |
| 38 | case $matchp in nil) echo >&2 "$0: hostname not permitted"; exit 2 ;; esac |
| 39 | } |
| 40 | |
| 41 | doupdate () { |
| 42 | cmd=$1 |
| 43 | |
| 44 | nsupdate -k "$DYNDNS_KEY" <<EOF |
| 45 | server $DYNDNS_SERVER |
| 46 | zone $DYNDNS_ZONE |
| 47 | $cmd |
| 48 | send |
| 49 | EOF |
| 50 | } |
| 51 | |
| 52 | eval $getarg; cmd=$arg |
| 53 | case "$cmd" in |
| 54 | set) |
| 55 | forcep=nil |
| 56 | eval $getarg |
| 57 | case "$arg" in -force) forcep=t; eval $getarg ;; esac |
| 58 | host=$arg |
| 59 | case "$#,$forcep,$1" in |
| 60 | 0,nil,*) addr=$client ;; |
| 61 | 0,t,*) fail_usage ;; |
| 62 | *,nil,"$client" | *,t,*) addr=$1; shift ;; |
| 63 | *) |
| 64 | echo >&2 "$0: incorrect address (wanted = $2; found = $addr)" |
| 65 | exit 3 |
| 66 | ;; |
| 67 | esac |
| 68 | eval $doneargs |
| 69 | checkhost "$host" |
| 70 | case $addr in |
| 71 | *:*) rrtype=AAAA ;; |
| 72 | *.*) rrtype=A ;; |
| 73 | *) echo >&2 "$0: failed to parse new address"; exit 2 ;; |
| 74 | esac |
| 75 | name=$host.$DYNDNS_ZONE |
| 76 | doupdate " |
| 77 | update delete $name IN $rrtype |
| 78 | update add $name ${DYNDNS_TTL-14400} IN $rrtype $addr" |
| 79 | ;; |
| 80 | unset) |
| 81 | eval $getarg; host=$arg |
| 82 | eval $doneargs |
| 83 | checkhost "$host" |
| 84 | name=$host.$DYNDNS_ZONE |
| 85 | doupdate "update delete $name IN" |
| 86 | ;; |
| 87 | *) |
| 88 | fail_usage |
| 89 | ;; |
| 90 | esac |