From: Douglas Bagnall Date: Fri, 28 May 2021 07:09:17 +0000 (+1200) Subject: rpc:dnsserver: allow update replacing with similar record X-Git-Tag: tevent-0.11.0~155 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9fb87134b8c3455940d502e13aa622234cf37b2c;p=thirdparty%2Fsamba.git rpc:dnsserver: allow update replacing with similar record We have been refusing to handle the case where the replaced record matches the replacement according to dns_record_match() (meaning the wType and data are semantically identical). In Windows this is explicitly used for changing TTL. There are further changes we need to properly handle this case. Signed-off-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- diff --git a/selftest/knownfail.d/dns-aging b/selftest/knownfail.d/dns-aging index f585449e1f9..bcea8011872 100644 --- a/selftest/knownfail.d/dns-aging +++ b/selftest/knownfail.d/dns-aging @@ -35,8 +35,6 @@ samba.tests.dns_aging.+test_add_update_dwReserved samba.tests.dns_aging.+test_add_update_dwSerial samba.tests.dns_aging.+test_add_update_dwSerial_2 samba.tests.dns_aging.+test_add_update_many -samba.tests.dns_aging.+test_add_update_timestamp -samba.tests.dns_aging.+test_add_update_ttl samba.tests.dns_aging.+test_add_update_ttl_serial samba.tests.dns_aging.+test_dns_delete_simple_0_0_days_no_aging_touch samba.tests.dns_aging.+test_dns_delete_simple_0_113_days_no_aging_touch @@ -53,7 +51,6 @@ samba.tests.dns_aging.+test_dns_delete_simple_2_13_days_no_aging_touch samba.tests.dns_aging.+test_dns_delete_simple_2_3_days_no_aging_touch samba.tests.dns_aging.+test_dynamic_record_static_update samba.tests.dns_aging.+test_multi_records_delete_aging -samba.tests.dns_aging.+test_rpc_update_timestamps samba.tests.dns_aging.+test_static_record_dynamic_update samba.tests.dns_aging.+test_update_aging_disabled\b samba.tests.dns_aging.+test_update_aging_disabled_beyond_refresh_window diff --git a/selftest/knownfail.d/dnscmd b/selftest/knownfail.d/dnscmd index 95860d2e9c2..5385997ab50 100644 --- a/selftest/knownfail.d/dnscmd +++ b/selftest/knownfail.d/dnscmd @@ -1,2 +1 @@ -samba.tests.samba_tool.dnscmd.+test_update_valid_type samba.tests.samba_tool.dnscmd.+test_update_invalid_type diff --git a/source4/rpc_server/dnsserver/dnsdb.c b/source4/rpc_server/dnsserver/dnsdb.c index 33e73879248..3323000530f 100644 --- a/source4/rpc_server/dnsserver/dnsdb.c +++ b/source4/rpc_server/dnsserver/dnsdb.c @@ -570,12 +570,14 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx, { const char * const attrs[] = { "dnsRecord", NULL }; struct ldb_result *res; + struct dnsp_DnssrvRpcRecord rec2; struct dnsp_DnssrvRpcRecord *arec = NULL, *drec = NULL; struct ldb_message_element *el; enum ndr_err_code ndr_err; int ret, i; int serial; WERROR werr; + bool updating_ttl = false; char *encoded_name = ldb_binary_encode_string(mem_ctx, name); werr = dns_to_dnsp_convert(mem_ctx, add_record, &arec, true); @@ -607,8 +609,6 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx, } for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec2; - ndr_err = ndr_pull_struct_blob(&el->values[i], mem_ctx, &rec2, (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -620,13 +620,22 @@ WERROR dnsserver_db_update_record(TALLOC_CTX *mem_ctx, } } if (i < el->num_values) { - return WERR_DNS_ERROR_RECORD_ALREADY_EXISTS; + /* + * The record already exists, which is an error UNLESS we are + * doing an in-place update. + * + * Therefore we need to see if drec also matches, in which + * case it's OK, though we can only update dwTtlSeconds and + * reset the timestamp to zero. + */ + updating_ttl = dns_record_match(drec, &rec2); + if (! updating_ttl) { + return WERR_DNS_ERROR_RECORD_ALREADY_EXISTS; + } + /* In this case the next loop is redundant */ } - for (i=0; inum_values; i++) { - struct dnsp_DnssrvRpcRecord rec2; - ndr_err = ndr_pull_struct_blob(&el->values[i], mem_ctx, &rec2, (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnssrvRpcRecord); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {