summaryrefslogtreecommitdiff
path: root/bin/cryptonomic-dyndns-command
blob: 348ed749d9c77309ae2ed449c60d1a283a778cdc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#!/bin/bash

die() { printf 'Error: %s\n' "$*" >&2; exit 1; }

warn() { printf 'Warning: %s\n' "$*" >&2; }

sql_string()
{
	printf '%s' "'${1//\'/\'\'}'"
}

powerdns_sqlite_add_replace_record()
{
	local sql_record_type="$(sql_string "$2")"
	local sql_ip_address="$(sql_string "$3")"

	zone=${1#*.}
	new_name=${label:+$label.}${1: -64 : 64}

	local sql_new_name="$(sql_string "$new_name")"
	local sql_zone="$(sql_string "$zone")"

	if false
	then
		pdnsutil create-zone "$zone"
		pdnsutil add-record "$zone" "$new_name" "$2" "$3"
		return
	fi

	DBDIR=/etc/powerdns
	DBNAME=powerdns.sqlite3
	DB=$DBDIR/$DBNAME

	test -r $DB    && test -w $DB    || die "Wrong permissions on $DB"
	test -r $DBDIR && test -w $DBDIR || die "Wrong permissions on $DBDIR"

	sqlite3 $DB <<END
${SQL_ECHO:+.echo on}
BEGIN;
	DELETE FROM records WHERE type=$sql_record_type AND name=$sql_new_name;

	INSERT INTO records

		(domain_id,
		name,
		type,
		content,
		ttl,
		prio)

		SELECT
			id,
			$sql_new_name,
			$sql_record_type,
			$sql_ip_address,
			3600,
			0
		FROM domains
		WHERE name=$sql_zone;
COMMIT;
END
	r=$?
	[ $r = 0 ] || return $r

	printf '%s %s\n' "$new_name" "$3"
}

add()
{
        local label=
        if [ $# = 3 ]
        then
                label=$1
                shift
        fi
	local record_type ip="$2"
	case "$ip" in
		*.*.*.*) record_type=A ;;
		*:*) record_type=AAAA ;;
		*) exit 1 ;;
	esac

	powerdns_sqlite_add_replace_record "$domain" "$record_type" "$ip"
}

validate_dns_label()
{
	if [ $#1 -gt 64 ]
	then
		warn "ignored DNS label: too long"
		return 1
	fi
	case "$1" in
	-*|*--*|*-)
		warn 'ignored DNS label: invalid use of hyphens'
		return 2
		;;
	*[^-A-Za-z0-9]*)
		warn 'ignored DNS label: invalid character'
		return 3
		;;
	esac
	true
}

main()
{
	add "$domain" "$ip_address"
	for label in $SSH_ORIGINAL_COMMAND
	do
		validate_dns_label "$label" || continue
		add "$label" "$domain" "$ip_address"
	done
}

PEM_DEST=$HOME/public_rsync

eval "$(samizdat-ssh-uid --copy-pem "$PEM_DEST")"

domain=${SSH_CLIENT_DOMAIN}
ip_address=${SSH_CLIENT%% *}

main "$@"