Forbid empty DNS names
[regano.git] / db_types.sql
blob424f4076b6b3eba5db5d4449aaddd1cef91eb26a
1 -- Regano database type definitions
2 --
3 -- Uses PostgreSQL extensions.
4 --
5 --  Regano is a domain registration system for OpenNIC TLDs written in
6 --  Perl.  This file is part of Regano.
7 --
8 --  Regano may be distributed under the same terms as Perl itself.  Of
9 --  particular importance, note that while regano is distributed in the
10 --  hope that it will be useful, there is NO WARRANTY OF ANY KIND
11 --  WHATSOEVER WHETHER EXPLICIT OR IMPLIED.
14 -- The role 'regano' must already exist.
16 CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;
18 CREATE SCHEMA IF NOT EXISTS regano AUTHORIZATION regano;
19 CREATE SCHEMA IF NOT EXISTS regano_api AUTHORIZATION regano;
21 -- This is an unsigned 8 bit integer.
22 CREATE DOMAIN regano.uint8bit AS smallint
23         CHECK(VALUE >= 0 AND VALUE < 256);
24 -- This is an unsigned 16 bit integer.
25 CREATE DOMAIN regano.uint16bit AS integer
26         CHECK(VALUE >= 0 AND VALUE < 65536);
27 -- This is an unsigned 32 bit integer.
28 CREATE DOMAIN regano.uint32bit AS bigint
29         CHECK(VALUE >= 0 AND VALUE < 4294967296);
30 -- This is an interval, less than 2^31 seconds long.
31 CREATE DOMAIN regano.dns_interval AS interval
32         CHECK(EXTRACT(EPOCH FROM VALUE)::bigint < 2147483648);
33 -- This is binary data, as hexadecimal digits.
34 CREATE DOMAIN regano.hexstring AS text
35         CHECK(VALUE SIMILAR TO '([0123456789ABCDEF]{2})+');
36 -- This is binary data, in Base64.
37 CREATE DOMAIN regano.base64string AS text
38         CHECK(VALUE ~ '^[[:alnum:]+/-_]+=*$');
39 -- This is a single label in the DNS.
40 CREATE DOMAIN regano.dns_label AS text
41         CHECK(octet_length(VALUE) <= 63)        -- per RFC 1035 2.3.4
42         CHECK(octet_length(VALUE) >=  1)
43         CHECK(VALUE NOT LIKE '%.%');
44 -- This is a name in the DNS.
45 CREATE DOMAIN regano.dns_name AS text
46         CHECK(octet_length(VALUE) <= 255)       -- per RFC 1035 2.3.4
47         CHECK(octet_length(VALUE) >=  1)
48         CHECK(VALUE NOT LIKE '%..%');
49 -- This is a Fully Qualified Domain Name.
50 CREATE DOMAIN regano.dns_fqdn AS regano.dns_name
51         CHECK(VALUE LIKE '%.');
52 -- This is an email address, encoded into a DNS name.
53 CREATE DOMAIN regano.dns_email AS regano.dns_fqdn
54         CHECK(VALUE LIKE '%.%.%.');
56 ALTER DOMAIN regano.uint8bit            OWNER TO regano;
57 ALTER DOMAIN regano.uint16bit           OWNER TO regano;
58 ALTER DOMAIN regano.uint32bit           OWNER TO regano;
59 ALTER DOMAIN regano.dns_interval        OWNER TO regano;
60 ALTER DOMAIN regano.hexstring           OWNER TO regano;
61 ALTER DOMAIN regano.base64string        OWNER TO regano;
62 ALTER DOMAIN regano.dns_name            OWNER TO regano;
63 ALTER DOMAIN regano.dns_fqdn            OWNER TO regano;
64 ALTER DOMAIN regano.dns_email           OWNER TO regano;
66 -- This bundles together type information, two salts, and a password hash.
67 CREATE TYPE regano.password AS (
68         -- external digest
69         xdigest         text,
70         -- salt for external digest
71         xsalt           text,
72         -- hashed password (with internal salt)
73         digest          text
75 -- The password type is used both for storing passwords in the DB and for
76 -- communications between the DB and frontend.  In the DB, the "digest"
77 -- field stores a digest value from crypt().  When reading salts, the
78 -- "xdigest" and "xsalt" fields contain the external digest algorithm and
79 -- external salt, while "digest" is null.  When attempting a login, the
80 -- "digest" field contains the password, salted and hashed according to
81 -- "xdigest" and "xsalt", which the DB will run through crypt() and then
82 -- compare with the stored password.  If they match, a session is opened.
84 -- These are the types of contact verifications implemented.
85 CREATE TYPE regano.contact_verification_type AS ENUM (
86         'account_recovery',
87         'email_address'
89 ALTER TYPE regano.contact_verification_type OWNER TO regano;
91 -- These are the DNS record classes defined in RFC 1035.
92 CREATE TYPE regano.dns_record_class AS ENUM (
93         'IN',   -- Internet
94         'CS',   -- CSNET (obsolete even before RFC 1035)
95         'CH',   -- CHAOSnet
96         'HS'    -- Hesiod
99 -- The allowed record types are a subset of those supported in BIND.
100 CREATE TYPE regano.dns_record_type AS ENUM (
101         'SOA',          -- RFC 1035: start of authority record
102         'A',            -- RFC 1035: IPv4 address
103         'AAAA',         -- RFC 1886: IPv6 address
104         'CERT',         -- RFC 2538: certificate, including PGP key
105         'CNAME',        -- RFC 1035: canonical name of alias
106         'DNAME',        -- RFC 2672: delegation alias
107         -- TODO: are DNSSEC records other than DS needed?
108         'DS',           -- RFC 4034: delegation signer
109         'IPSECKEY',     -- RFC 4025: IPsec public key
110         'LOC',          -- RFC 1876: physical location ("ICBM address")
111         'MX',           -- RFC 1035: mail exchange
112         'NAPTR',        -- RFC 2915: regex URI rewrite
113         'NS',           -- RFC 1035: authoritative name server
114         'PTR',          -- RFC 1035: domain name pointer
115         'RP',           -- RFC 1183: responsible person
116         'SPF',          -- RFC 4408: Sender Policy Framework record
117         'SRV',          -- RFC 2782: service location
118         'SSHFP',        -- RFC 4255: SSH host key fingerprint
119         'TLSA',         -- RFC 6698: DANE TLSA
120         'TXT'           -- RFC 1035: general descriptive text
123 ALTER TYPE regano.dns_record_class      OWNER TO regano;
124 ALTER TYPE regano.dns_record_type       OWNER TO regano;
126 -- SOA RDATA per RFC 1035 3.3.13
127 CREATE TYPE regano.dns_RR_SOA AS (
128         -- MNAME:       zone master nameserver
129         master          regano.dns_name,
130         -- RNAME:       email address for zone admin
131         mbox            regano.dns_email,
132 --      NOTE: The database does not store zone serial numbers.  The export
133 --      process assigns a serial number based on the domain's timestamp.
134 --      -- SERIAL:      zone data revision
135 --      serial          regano.uint32bit,
136         -- REFRESH:     refresh interval
137         refresh         regano.dns_interval,
138         -- RETRY:       retry interval if refresh fails
139         retry           regano.dns_interval,
140         -- EXPIRE:      lifespan of zone data if refresh continues to fail
141         expire          regano.dns_interval,
142         -- MINIMUM:     minimum TTL of any record in this zone
143         minimum         regano.dns_interval
145 ALTER TYPE regano.dns_RR_SOA            OWNER TO regano;
147 -- A RDATA per RFC 1035 3.4.1
148 CREATE DOMAIN regano.dns_RR_A AS inet
149         CONSTRAINT "an A record must hold an IPv4 address"
150                 CHECK(family(VALUE) = 4 AND masklen(VALUE) = 32);
151 ALTER DOMAIN regano.dns_RR_A            OWNER TO regano;
153 -- AAAA RDATA per RFC 1886
154 CREATE DOMAIN regano.dns_RR_AAAA AS inet
155         CONSTRAINT "an AAAA record must hold an IPv6 address"
156                 CHECK(family(VALUE) = 6 AND masklen(VALUE) = 128);
157 ALTER DOMAIN regano.dns_RR_AAAA         OWNER TO regano;
159 -- CERT RDATA per RFC 2538
160 CREATE TYPE regano.dns_RR_CERT AS (
161        type             regano.uint16bit,
162        key_tag          regano.uint16bit,
163        algorithm        regano.uint8bit,
164        certificate      regano.base64string
166 ALTER TYPE regano.dns_RR_CERT           OWNER TO regano;
168 -- CNAME RDATA per RFC 1035 3.3.1
169 -- use common "data_name" field
171 -- DNAME RDATA per RFC 2672
172 -- use common "data_name" field
174 -- DS RDATA per RFC 4034
175 CREATE TYPE regano.dns_RR_DS AS (
176         key_tag         regano.uint16bit,
177         algorithm       regano.uint8bit,
178         digest_type     regano.uint8bit,
179         digest          regano.hexstring
181 ALTER TYPE regano.dns_RR_DS             OWNER TO regano;
183 -- IPSECKEY RDATA per RFC 4025
184 CREATE TYPE regano.dns_RR_IPSECKEY_gateway_type AS ENUM (
185         '0:None', '1:IPv4', '2:IPv6', '3:DNS'
187 CREATE TYPE regano.dns_RR_IPSECKEY AS (
188         precedence      regano.uint8bit,
189         gateway_type    regano.dns_RR_IPSECKEY_gateway_type,
190         algorithm       regano.uint8bit,
191         gateway_dns     regano.dns_fqdn,
192         gateway_inet    inet,
193         public_key      regano.base64string
195 ALTER TYPE regano.dns_RR_IPSECKEY_gateway_type OWNER TO regano;
196 ALTER TYPE regano.dns_RR_IPSECKEY       OWNER TO regano;
198 -- LOC RDATA per RFC 1876
199 CREATE DOMAIN regano.dns_RR_LOC AS text
200         CHECK(VALUE SIMILAR TO
201                  (  '(90|[0-8]?[0-9])( [0-5]?[0-9]( [0-5]?[0-9.]+)?)? [NS] '
202                   ||'(180|1[0-7][0-9]|0?[0-9]{1,2})'
203                   ||'( [0-5]?[0-9]( [0-5]?[0-9.]+)?)? [EW] '
204                   ||'(-1?[0-9]{1,5}|[0-3]?[0-9]{1,7})([.][0-9]{0,2})?m?'
205                   ||'( (90000000|[0-8]?[0-9]{1,7})([.][0-9]{0,2})?){0,3}'));
206 ALTER DOMAIN regano.dns_RR_LOC          OWNER TO regano;
208 -- MX RDATA per RFC 1035 3.3.9
209 CREATE TYPE regano.dns_RR_MX AS (
210         preference      regano.uint16bit,
211         exchange        regano.dns_name
213 ALTER TYPE regano.dns_RR_MX             OWNER TO regano;
215 -- NAPTR RDATA per RFC 2915
216 CREATE TYPE regano.dns_RR_NAPTR AS (
217         naptr_order             regano.uint16bit,
218         naptr_preference        regano.uint16bit,
219         flags                   text,
220         services                text,
221         regexp                  text,
222         replacement             regano.dns_fqdn
224 ALTER TYPE regano.dns_RR_NAPTR          OWNER TO regano;
226 -- NS RDATA per RFC 1035 3.3.11
227 -- use common "data_name" field
229 -- PTR RDATA per RFC 1035 3.3.12
230 -- use common "data_name" field
232 -- RP RDATA per RFC 1183 2
233 CREATE TYPE regano.dns_RR_RP AS (
234         mbox            regano.dns_fqdn, -- should be dns_email, but may be "."
235         txt_ref         regano.dns_fqdn
237 ALTER TYPE regano.dns_RR_RP             OWNER TO regano;
239 -- SPF RDATA per RFC 4408
240 -- use common "data_text" field
242 -- SRV RDATA per RFC 2782
243 CREATE TYPE regano.dns_RR_SRV AS (
244         priority        regano.uint16bit,
245         weight          regano.uint16bit,
246         port            regano.uint16bit,
247         target          regano.dns_fqdn
249 ALTER TYPE regano.dns_RR_SRV            OWNER TO regano;
251 -- SSHFP RDATA per RFC 4255
252 CREATE TYPE regano.dns_RR_SSHFP AS (
253         algorithm       regano.uint8bit,
254         fp_type         regano.uint8bit,
255         fingerprint     regano.hexstring
257 ALTER TYPE regano.dns_RR_SSHFP          OWNER TO regano;
259 -- TLSA RDATA per RFC 6698
260 CREATE TYPE regano.dns_RR_TLSA AS (
261         cert_usage      regano.uint8bit,
262         selector        regano.uint8bit,
263         match_type      regano.uint8bit,
264         cert_data       regano.hexstring
266 ALTER TYPE regano.dns_RR_TLSA           OWNER TO regano;
268 -- TXT RDATA per RFC 1035 3.3.14
269 -- use common "data_text" field
273 -- Any domain is in one of 7 states:
275 --  - RESERVED
276 --      Not available for registration.
277 --  - ELSEWHERE
278 --      Not in a TLD managed by this server.
279 --  - BAILIWICK
280 --      Is itself a TLD managed by this server.
281 --  - AVAILABLE
282 --      May be registered.
283 --  - PENDING
284 --      Pre-registered but owning account not yet validated.
285 --  - REGISTERED
286 --      Currently registered and active.
287 --  - EXPIRED
288 --      Registration has expired, but has not yet been released.
290 CREATE TYPE regano.domain_status AS ENUM (
291         'RESERVED',
292         'ELSEWHERE',
293         'BAILIWICK',
294         'AVAILABLE',
295         'PENDING',
296         'REGISTERED',
297         'EXPIRED'
299 ALTER TYPE regano.domain_status         OWNER TO regano;
302 -- Each registered domain is in one of 3 modes:
304 --  - INLINE
305 --      All records for this domain are in the main TLD zone.
306 --  - HOSTED
307 --      This domain has its own zone on the main TLD server.
308 --  - DELEGATED
309 --      This domain has its own authoritative server(s).
311 CREATE TYPE regano.domain_mode AS ENUM ('INLINE', 'HOSTED', 'DELEGATED');
312 ALTER TYPE regano.domain_mode           OWNER TO regano;
314 -- This is summary information for a pending domain.
315 CREATE TYPE regano.pending_domain AS (
316         name            text,
317         start           timestamp with time zone,
318         expire          timestamp with time zone
321 -- This is summary information for a registered domain.
322 CREATE TYPE regano.domain AS (
323         name            text,
324         registered      timestamp with time zone,
325         expiration      timestamp with time zone,
326         last_update     timestamp with time zone,
327         -- status will be either REGISTERED or EXPIRED
328         status          regano.domain_status