]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
rpc dns: reset dword aging related zone properties
authorAaron Haslett <aaronhaslett@catalyst.net.nz>
Tue, 3 Jul 2018 03:34:32 +0000 (15:34 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 12 Jul 2018 02:31:53 +0000 (04:31 +0200)
This allows a user to set zone properties relevant to DNS record aging over RPC.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=10812

Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Reviewed-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/dns.py
selftest/knownfail.d/dns
selftest/knownfail.d/dns-scavenging
source4/rpc_server/dnsserver/dcerpc_dnsserver.c
source4/rpc_server/dnsserver/dnsdb.c
source4/rpc_server/dnsserver/dnsserver.h

index 083dc460afd7e3cafb2f9fc8410632c33fe79f47..722b75ce81b8b87fefcfaf8c46fac01337eb124b 100644 (file)
@@ -1040,6 +1040,7 @@ class TestZones(DNSTest):
             self.set_params(zone=self.zone, Aging=0)
         dec = 2
         def mod_ts(rec):
+            self.assertTrue(rec.dwTimeStamp > 0)
             rec.dwTimeStamp -= dec
         self.ldap_modify_dnsrecs(name, mod_ts)
         after_mod = self.ldap_get_dns_records(name)
@@ -1064,10 +1065,12 @@ class TestZones(DNSTest):
                         AllowUpdate = dnsp.DNS_ZONE_UPDATE_UNSECURE)
         before_mod = self.dns_update_record(name, txt)
         def mod_ts(rec):
+            self.assertTrue(rec.dwTimeStamp > 0)
             rec.dwTimeStamp -= interval/2
         self.ldap_modify_dnsrecs(name, mod_ts)
         update_during_norefresh = self.dns_update_record(name, txt)
         def mod_ts(rec):
+            self.assertTrue(rec.dwTimeStamp > 0)
             rec.dwTimeStamp -= interval + interval/2
         self.ldap_modify_dnsrecs(name, mod_ts)
         update_during_refresh = self.dns_update_record(name, txt)
@@ -1098,6 +1101,7 @@ class TestZones(DNSTest):
         rec = self.dns_update_record(name,txt)
         rec = self.dns_update_record(name+'2',txt)
         def mod_ts(rec):
+            self.assertTrue(rec.dwTimeStamp > 0)
             rec.dwTimeStamp -= interval*5
         self.ldap_modify_dnsrecs(name, mod_ts)
         dsdb._scavenge_dns_records(self.samdb)
index 9fa35a2b6ea8b9be63037b40975fc5bcf1c4999b..4beeabf4386c6476f4e35c8fa6b19828bbb785cb 100644 (file)
@@ -34,7 +34,8 @@ samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_slash_rpc_to_dns\(rodc
 samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_two_rpc_to_dns\(rodc:local\)
 samba.tests.dns.__main__.TestRPCRoundtrip.test_update_add_txt_rpc_to_dns\(rodc:local\)
 
-samba.tests.dns.__main__.TestZones.test_set_aging_disabled
+samba.tests.dns.__main__.TestZones.test_set_aging_disabled\(rodc:local\)
+samba.tests.dns.__main__.TestZones.test_set_aging_disabled\(vampire_dc:local\)
 
 samba.tests.dns.__main__.TestZones.test_soa_query\(rodc:local\)
 samba.tests.dns.__main__.TestZones.test_set_aging\(rodc:local\)
index 3c4cdc97a78b3db8a109d85643f7c5275a881916..715e14527c9a2e16534a3be1b547dab431712fed 100644 (file)
@@ -7,6 +7,5 @@ samba.tests.dns.__main__.TestZones.test_aging_refresh\(fl2003dc:local\)
 samba.tests.dns.__main__.TestZones.test_aging_update\(fl2003dc:local\)
 samba.tests.dns.__main__.TestZones.test_aging_update_disabled\(fl2003dc:local\)
 samba.tests.dns.__main__.TestZones.test_basic_scavenging\(fl2003dc:local\)
-samba.tests.dns.__main__.TestZones.test_rpc_add_no_timestamp\(fl2003dc:local\)
 samba.tests.dns.__main__.TestZones.test_set_aging\(fl2003dc:local\)
-samba.tests.dns.__main__.TestZones.test_rpc_add_no_timestamp\(vampire_dc:local\)
+samba.tests.dns.__main__.TestZones.test_set_aging_disabled\(fl2003dc:local\)
index c342ccadfc9c7f60b7935eb6ba41f62622c093d0..b42d7c549d10db8170eecb6eaaed9dc3bab1f239 100644 (file)
@@ -1512,16 +1512,14 @@ static WERROR dnsserver_operate_zone(struct dnsserver_state *dsstate,
        bool valid_operation = false;
 
        if (strcasecmp(operation, "ResetDwordProperty") == 0) {
+
                if (typeid != DNSSRV_TYPEID_NAME_AND_PARAM) {
                        return WERR_DNS_ERROR_INVALID_PROPERTY;
                }
 
-               /* Ignore property resets */
-               if (strcasecmp(r->NameAndParam->pszNodeName, "AllowUpdate") ==
-                   0) {
-                       return WERR_OK;
-               }
-               valid_operation = true;
+               return dnsserver_db_do_reset_dword(dsstate->samdb, z,
+                                                  r->NameAndParam);
+
        } else if (strcasecmp(operation, "ZoneTypeReset") == 0) {
                valid_operation = true;
        } else if (strcasecmp(operation, "PauseZone") == 0) {
index cdd6c0258b659e7ee5ab5e802e84fb7ea156721d..350e29aa1e0c3156b87c78ee143f81302c6a6f1b 100644 (file)
@@ -733,6 +733,129 @@ static bool dnsserver_db_msg_add_dnsproperty(TALLOC_CTX *mem_ctx,
        return true;
 }
 
+WERROR dnsserver_db_do_reset_dword(struct ldb_context *samdb,
+                                  struct dnsserver_zone *z,
+                                  struct DNS_RPC_NAME_AND_PARAM *n_p)
+{
+       struct ldb_message_element *element = NULL;
+       struct dnsp_DnsProperty *prop = NULL;
+       enum ndr_err_code err;
+       TALLOC_CTX *tmp_ctx = NULL;
+       const char * const attrs[] = {"dNSProperty", NULL};
+       struct ldb_result *res = NULL;
+       int i, ret, prop_id;
+
+       if (strcasecmp(n_p->pszNodeName, "Aging") == 0) {
+               z->zoneinfo->fAging = n_p->dwParam;
+               prop_id = DSPROPERTY_ZONE_AGING_STATE;
+       } else if (strcasecmp(n_p->pszNodeName, "RefreshInterval") == 0) {
+               z->zoneinfo->dwRefreshInterval = n_p->dwParam;
+               prop_id = DSPROPERTY_ZONE_REFRESH_INTERVAL;
+       } else if (strcasecmp(n_p->pszNodeName, "NoRefreshInterval") == 0) {
+               z->zoneinfo->dwNoRefreshInterval = n_p->dwParam;
+               prop_id = DSPROPERTY_ZONE_NOREFRESH_INTERVAL;
+       } else if (strcasecmp(n_p->pszNodeName, "AllowUpdate") == 0) {
+               z->zoneinfo->fAllowUpdate = n_p->dwParam;
+               prop_id = DSPROPERTY_ZONE_ALLOW_UPDATE;
+       } else {
+               return WERR_UNKNOWN_PROPERTY;
+       }
+
+       tmp_ctx = talloc_new(NULL);
+       if (tmp_ctx == NULL) {
+               return WERR_NOT_ENOUGH_MEMORY;
+       }
+
+       ret = ldb_search(samdb, tmp_ctx, &res, z->zone_dn, LDB_SCOPE_BASE,
+                        attrs, "(objectClass=dnsZone)");
+       if (ret != LDB_SUCCESS) {
+               DBG_ERR("dnsserver: no zone: %s\n",
+                       ldb_dn_get_linearized(z->zone_dn));
+               TALLOC_FREE(tmp_ctx);
+               return WERR_INTERNAL_DB_ERROR;
+       }
+
+       if (res->count != 1) {
+               DBG_ERR("dnsserver: duplicate zone: %s\n",
+                       ldb_dn_get_linearized(z->zone_dn));
+               TALLOC_FREE(tmp_ctx);
+               return WERR_GEN_FAILURE;
+       }
+
+       element = ldb_msg_find_element(res->msgs[0], "dNSProperty");
+       if (element == NULL) {
+               DBG_ERR("dnsserver: zone %s has no properties.\n",
+                       ldb_dn_get_linearized(z->zone_dn));
+               TALLOC_FREE(tmp_ctx);
+               return WERR_INTERNAL_DB_ERROR;
+       }
+
+       for (i = 0; i < element->num_values; i++) {
+               prop = talloc_zero(element, struct dnsp_DnsProperty);
+               if (prop == NULL) {
+                       TALLOC_FREE(tmp_ctx);
+                       return WERR_NOT_ENOUGH_MEMORY;
+               }
+               err = ndr_pull_struct_blob(
+                       &(element->values[i]),
+                       tmp_ctx,
+                       prop,
+                       (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnsProperty);
+               if (!NDR_ERR_CODE_IS_SUCCESS(err)){
+                       DBG_ERR("dnsserver: couldn't PULL dns property id "
+                               "%d in zone %s\n",
+                               prop->id,
+                               ldb_dn_get_linearized(z->zone_dn));
+                       TALLOC_FREE(tmp_ctx);
+                       return WERR_INTERNAL_DB_ERROR;
+               }
+
+               if (prop->id == prop_id) {
+                       switch (prop_id) {
+                       case DSPROPERTY_ZONE_AGING_STATE:
+                               prop->data.aging_enabled = n_p->dwParam;
+                               break;
+                       case DSPROPERTY_ZONE_NOREFRESH_INTERVAL:
+                               prop->data.norefresh_hours = n_p->dwParam;
+                               break;
+                       case DSPROPERTY_ZONE_REFRESH_INTERVAL:
+                               prop->data.refresh_hours = n_p->dwParam;
+                               break;
+                       case DSPROPERTY_ZONE_ALLOW_UPDATE:
+                               prop->data.allow_update_flag = n_p->dwParam;
+                               break;
+                       }
+
+                       err = ndr_push_struct_blob(
+                               &(element->values[i]),
+                               tmp_ctx,
+                               prop,
+                               (ndr_push_flags_fn_t)ndr_push_dnsp_DnsProperty);
+                       if (!NDR_ERR_CODE_IS_SUCCESS(err)){
+                               DBG_ERR("dnsserver: couldn't PUSH dns prop id "
+                                       "%d in zone %s\n",
+                                       prop->id,
+                                       ldb_dn_get_linearized(z->zone_dn));
+                               TALLOC_FREE(tmp_ctx);
+                               return WERR_INTERNAL_DB_ERROR;
+                       }
+               }
+       }
+
+       element->flags = LDB_FLAG_MOD_REPLACE;
+       ret = ldb_modify(samdb, res->msgs[0]);
+       if (ret != LDB_SUCCESS) {
+               TALLOC_FREE(tmp_ctx);
+               DBG_ERR("dnsserver: Failed to modify zone %s prop %s: %s\n",
+                       z->name,
+                       n_p->pszNodeName,
+                       ldb_errstring(samdb));
+               return WERR_INTERNAL_DB_ERROR;
+       }
+       TALLOC_FREE(tmp_ctx);
+
+       return WERR_OK;
+}
 
 /* Create dnsZone record to database and set security descriptor */
 static WERROR dnsserver_db_do_create_zone(TALLOC_CTX *tmp_ctx,
index 83dccf5e6c55089fd2bc400b8ec69fb355d0412b..6948fb5d42d9d016176082fea229c7120d5efb3b 100644 (file)
@@ -249,6 +249,9 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx,
                                        const char *node_name,
                                        struct DNS_RPC_RECORD *add_record,
                                        struct DNS_RPC_RECORD *del_record);
+WERROR dnsserver_db_do_reset_dword(struct ldb_context *samdb,
+                                       struct dnsserver_zone *z,
+                                       struct DNS_RPC_NAME_AND_PARAM *n_p);
 WERROR dnsserver_db_delete_record(TALLOC_CTX *mem_ctx,
                                  struct ldb_context *samdb,
                                  struct dnsserver_zone *z,