diff --git a/python/samba/tests/dns.py b/python/samba/tests/dns.py index 083dc460afd..722b75ce81b 100644 --- a/python/samba/tests/dns.py +++ b/python/samba/tests/dns.py @@ -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) diff --git a/selftest/knownfail.d/dns b/selftest/knownfail.d/dns index 9fa35a2b6ea..4beeabf4386 100644 --- a/selftest/knownfail.d/dns +++ b/selftest/knownfail.d/dns @@ -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\) diff --git a/selftest/knownfail.d/dns-scavenging b/selftest/knownfail.d/dns-scavenging index 3c4cdc97a78..715e14527c9 100644 --- a/selftest/knownfail.d/dns-scavenging +++ b/selftest/knownfail.d/dns-scavenging @@ -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\) diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index c342ccadfc9..b42d7c549d1 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -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) { diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c index cdd6c0258b6..350e29aa1e0 100644 --- a/source4/rpc_server/dnsserver/dnsdb.c +++ b/source4/rpc_server/dnsserver/dnsdb.c @@ -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, diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h index 83dccf5e6c5..6948fb5d42d 100644 --- a/source4/rpc_server/dnsserver/dnsserver.h +++ b/source4/rpc_server/dnsserver/dnsserver.h @@ -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,