From 42d23c7d92501f8ad29ff62fbc6c521bd7fe62d7 Mon Sep 17 00:00:00 2001 From: Daniel Hilst Selli <392820+dhilst@users.noreply.github.com> Date: Fri, 20 Mar 2026 13:26:46 -0300 Subject: [PATCH] fix: Fix regresion in makedns in update mode Signed-off-by: Daniel Hilst Selli <392820+dhilst@users.noreply.github.com> --- xCAT-server/lib/xcat/plugins/ddns.pm | 61 +++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/ddns.pm b/xCAT-server/lib/xcat/plugins/ddns.pm index fb0b79830..f5f0ce5d1 100644 --- a/xCAT-server/lib/xcat/plugins/ddns.pm +++ b/xCAT-server/lib/xcat/plugins/ddns.pm @@ -25,6 +25,39 @@ my $service = "named"; my $ddns_key_path = "/etc/xcat/ddns.key"; +# Net::DNS >= 1.36 removed support for sign_tsig($keyname, $secret) and now +# expects a keyfile. Keep the keyfile in sync with the xcat_key secret. +sub ensure_ddns_key_file { + my ($ctx) = @_; + + return unless (Net::DNS->VERSION >= 1.36); + return unless ($ctx && $ctx->{privkey}); + + my $algorithm = $ctx->{tsig_algorithm} || "hmac-sha256"; + my $contents = + "key \"xcat_key\" {\n" + . "\talgorithm $algorithm;\n" + . "\tsecret \"" . $ctx->{privkey} . "\";\n" + . "};\n\n"; + + if (open(my $existing_fh, "<", $ddns_key_path)) { + local $/; + my $existing = <$existing_fh>; + close($existing_fh); + return if defined($existing) && $existing eq $contents; + } + + my $fh; + unless (open($fh, ">", $ddns_key_path)) { + my $rsp = {}; + $rsp->{data}->[0] = "Cannot open $ddns_key_path: $!"; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + print $fh $contents; + close($fh); +} + # is this ubuntu ? if ($distro =~ /ubuntu.*/i || $distro =~ /debian.*/i) { $service = "bind9"; @@ -1196,7 +1229,7 @@ sub update_namedconf { $i++; $line = $currnamed[$i]; push @candidate, $line; - if ($line =~ /key xcat_key/) { + if ($line =~ /key\s+\"?xcat_key\"?\b/) { $needreplace = 0; } } while ($line !~ /^\};/); #skip the old file zone @@ -1241,8 +1274,9 @@ sub update_namedconf { } while ($line !~ /^\};/); } - } elsif ($line =~ /^key xcat_key/) { + } elsif ($line =~ /^key\s+\"?xcat_key\"?\b/) { $gotkey = 1; + my $algorithmnow; if ($ctx->{privkey}) { #for now, assume the field is correct @@ -1251,20 +1285,29 @@ sub update_namedconf { do { $i++; $line = $currnamed[$i]; + if ($line =~ /^\s*algorithm\s+([^;\s]+)\s*;/) { + $algorithmnow = $1; + } push @newnamed, $line; } while ($line !~ /^\};/); } else { push @newnamed, $line; while ($line !~ /^\};/) { #skip the old file zone - if ($line =~ /secret \"([^"]*)\"/) { + if ($line =~ /^\s*algorithm\s+([^;\s]+)\s*;/) { + $algorithmnow = $1; + } elsif ($line =~ /secret \"([^"]*)\"/) { my $passtab = xCAT::Table->new("passwd", -create => 1); $passtab->setAttribs({ key => "omapi", username => "xcat_key" }, { password => $1 }); + $ctx->{privkey} = $1; } $i++; $line = $currnamed[$i]; push @newnamed, $line; } } + if ($algorithmnow) { + $ctx->{tsig_algorithm} = $algorithmnow; + } } elsif ($line !~ /generated by xCAT/) { push @newnamed, $line; } @@ -1363,15 +1406,13 @@ sub update_namedconf { $ctx->{privkey} = encode_base64(genpassword(32)); chomp($ctx->{privkey}); } - my $contents = "key \"xcat_key\" {\n". "\talgorithm hmac-sha256;\n". "\tsecret \"" . $ctx->{privkey} . "\";\n". "};\n\n"; - - if (Net::DNS->VERSION >= 1.36) { - open(my $fh, '>', $ddns_key_path) or die "Cannot open $ddns_key_path"; - print $fh $contents; - close $fh; - } + $ctx->{tsig_algorithm} ||= "hmac-sha256"; + my $contents = "key \"xcat_key\" {\n" . "\talgorithm " . $ctx->{tsig_algorithm} . ";\n" . "\tsecret \"" . $ctx->{privkey} . "\";\n" . "};\n\n"; push @newnamed, $contents; + ensure_ddns_key_file($ctx); $ctx->{restartneeded} = 1; + } else { + ensure_ddns_key_file($ctx); } }