From ef7b2d3c2e537e58f5d61e38d33e35442d7df84b Mon Sep 17 00:00:00 2001 From: wurzelpanzer <32928046+wurzelpanzer@users.noreply.github.com> Date: Sat, 22 Aug 2026 04:15:52 +0200 Subject: [PATCH] dns_easydns: match the TXT record by its rdata when removing (#7199) dns_easydns_rm() picked the first id in the search response and ignored $txtvalue. When two challenge records exist under the same host - for example when example.com and *.example.com are issued as separate certificates - a concurrent run's record could be deleted instead of our own. Select the record by its rdata instead, following the dns_cf.sh convention of matching name + value. tr '{' '\n' puts one record per line, so both _egrep_o branches - egrep -o and the BRE sed fallback - return the same single id. Without it the sed fallback would return only the last match, since .* is greedy. An empty record_id is now treated as "nothing to remove" and returns 0, rather than being reported as an error. Also add the credential check that _rm was missing. It deliberately does not call _saveaccountconf_mutable, as _add already does that. Co-authored-by: wurzelpanzer --- dnsapi/dns_easydns.sh | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/dnsapi/dns_easydns.sh b/dnsapi/dns_easydns.sh index 423def2b..2da45866 100644 --- a/dnsapi/dns_easydns.sh +++ b/dnsapi/dns_easydns.sh @@ -75,6 +75,11 @@ dns_easydns_rm() { EASYDNS_Token="${EASYDNS_Token:-$(_readaccountconf_mutable EASYDNS_Token)}" EASYDNS_Key="${EASYDNS_Key:-$(_readaccountconf_mutable EASYDNS_Key)}" + if [ -z "$EASYDNS_Token" ] || [ -z "$EASYDNS_Key" ]; then + _err "You didn't specify an easydns.net token or api key. Signup at https://cp.easydns.com/manage/security/api/signup.php" + return 1 + fi + _debug "First detect the root zone" if ! _get_root "$fulldomain"; then _err "invalid domain" @@ -91,24 +96,21 @@ dns_easydns_rm() { return 1 fi - count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) - _debug count "$count" - if [ "$count" = "0" ]; then + record_id=$(printf "%s\n" "$response" | tr '{' '\n' | grep "\"rdata\":\"$txtvalue\"" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \") + _debug "record_id" "$record_id" + + if [ -z "$record_id" ]; then _info "Don't need to remove." - else - record_id=$(printf "%s\n" "$response" | _egrep_o "\"id\":\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | head -n 1) - _debug "record_id" "$record_id" - if [ -z "$record_id" ]; then - _err "Can not get record id to remove." - return 1 - fi - if ! _EASYDNS_rest DELETE "zones/records/$_domain/$record_id"; then - _err "Delete record error." - return 1 - fi - _contains "$response" "\"status\":200" + return 0 fi + if ! _EASYDNS_rest DELETE "zones/records/$_domain/$record_id"; then + _err "Delete record error." + return 1 + fi + + _contains "$response" "\"status\":200" + } #################### Private functions below ##################################