]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
auth: api - Check if the DNSNames that should be hostnames, are hostnames
authorCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Thu, 23 Aug 2018 09:11:10 +0000 (11:11 +0200)
committerCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Wed, 31 Oct 2018 08:03:42 +0000 (09:03 +0100)
pdns/ws-auth.cc
regression-tests.api/test_Zones.py

index 1df76b16689b0d6872a466aca8ac6361c2623a1f..6d16b591a96c568c2bafb7daf349dc9f0fd48f0e 100644 (file)
@@ -1723,6 +1723,31 @@ static void patchZone(HttpRequest* req, HttpResponse* resp) {
             if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) {
               soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind);
             }
+
+            // Check if the DNSNames that should be hostnames, are hostnames
+            if (rr.qtype.getCode() == QType::NS || rr.qtype.getCode() == QType::MX || rr.qtype.getCode() == QType::SRV) {
+              DNSName toCheck;
+              if (rr.qtype.getCode() == QType::SRV) {
+                vector<string> parts;
+                stringtok(parts, rr.getZoneRepresentation());
+                if (parts.size() == 4) toCheck = DNSName(parts[3]);
+              } else if (rr.qtype.getCode() == QType::MX) {
+                vector<string> parts;
+                stringtok(parts, rr.getZoneRepresentation());
+                if (parts.size() == 2) toCheck = DNSName(parts[1]);
+              } else {
+                toCheck = DNSName(rr.content);
+              }
+
+              if (toCheck.empty()) {
+                throw ApiException("RRset "+qname.toString()+" IN "+qtype.getName() + " unable to extract hostname from content.");
+              }
+              else if ((rr.qtype.getCode() == QType::MX || rr.qtype.getCode() == QType::SRV) && toCheck == g_rootdnsname) {
+                // allow null MX/SRV
+              } else if(!toCheck.isHostname()) {
+                throw ApiException("RRset "+qname.toString()+" IN "+qtype.getName() + " record has non-hostname content '" + toCheck.toString() + "'.");
+              }
+            }
           }
           checkDuplicateRecords(new_records);
         }
index ef481ffedae5e3c49ba2395244f686639c833036..6081cc52f9ab2ac07ea3e29cf24fce28220493ba 100644 (file)
@@ -985,6 +985,31 @@ fred   IN  A      192.168.0.4
         data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json()
         self.assertEquals(get_rrset(data, name, 'MX')['records'], rrset['records'])
 
+    def test_zone_rr_update_invalid_mx(self):
+        name, payload, zone = self.create_zone()
+        # do a replace (= update)
+        rrset = {
+            'changetype': 'replace',
+            'name': name,
+            'type': 'MX',
+            'ttl': 3600,
+            'records': [
+                {
+                    "content": "10 mail@mx.example.org.",
+                    "disabled": False
+                }
+            ]
+        }
+        payload = {'rrsets': [rrset]}
+        r = self.session.patch(
+            self.url("/api/v1/servers/localhost/zones/" + name),
+            data=json.dumps(payload),
+            headers={'content-type': 'application/json'})
+        self.assertEquals(r.status_code, 422)
+        self.assertIn('record has non-hostname content', r.json()['error'])
+        data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json()
+        self.assertIsNone(get_rrset(data, name, 'MX'))
+
     def test_zone_rr_update_opt(self):
         name, payload, zone = self.create_zone()
         # do a replace (= update)