From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.haj.ipfire.org (localhost [IPv6:::1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4jFqBz1Fmvz2xWP for ; Thu, 29 Oct 2026 16:17:47 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [IPv6:2001:678:b28::25]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (Client CN "mail01.haj.ipfire.org", Issuer "YR1" (not verified)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4jFqBz0tr2z2xLm for ; Thu, 29 Oct 2026 16:17:47 +0000 (UTC) Received: from people01.haj.ipfire.org (people01.haj.ipfire.org [IPv6:2001:678:b28::161]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519) (Client CN "people01.haj.ipfire.org", Issuer "YE1" (not verified)) by mail01.ipfire.org (Postfix) with ESMTPS id 4jFqBx31Qqz470 for ; Thu, 29 Oct 2026 16:17:45 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1793290665; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc; bh=bnIIcPr7GinmmNYqK4lO1cp59xH8s84ycUDF/WiwtX0=; b=Pdj4Go1NzIeWyN9O4JvKhl22MG1xc392Yu96Ma21eTXcMtZXe/MZJ4zqBTq9c9Zltdu7eq 1D4uSzAiZhj3NZAg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1793290665; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc; bh=bnIIcPr7GinmmNYqK4lO1cp59xH8s84ycUDF/WiwtX0=; b=mZueel2BtD1CdSqpZwZ368RFgeBaxgognjzKTVHdMLM4Ni+qGbr+2woTog7Y6KomrmuZDj BeBZvw0sCNwp3r3Um+WF2ZJjdejfXIpJRNDMbJ0SnYdnohh02pZ4N43SsHl13TonDVdapl S4VL4jGIVeuKKt4frjQIGRkevlw5FL1U4dqj4IUQMvbhGZk+HDWXViTae9wJecsWFwetuD Bt+rnED5qDnuXJPYCecy7072kUxtdP8wuG8aVPHtTR8foD77XkXFCeQbAhVBfWvf9JptuZ BvoIHL32gmS3HptSwJ4nWAImRTOktW1xJJPvIyU2Gurrg/51xO3f6FUkFHGYEQ== Received: by people01.haj.ipfire.org (Postfix, from userid 1000) id 4jFqBv5HL0z2xMZ; Thu, 29 Oct 2026 16:17:43 +0000 (UTC) To: ipfire-scm@lists.ipfire.org Subject: [git.ipfire.org] IPFire 2.x development tree branch, master, updated. 7d93a465862e5b87d0de299053f27dc1e79f77b6 X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: d37aca7cfd4c62d04b4033e5a0a3a8bad9ce510e X-Git-Newrev: 7d93a465862e5b87d0de299053f27dc1e79f77b6 Message-Id: <4jFqBv5HL0z2xMZ@people01.haj.ipfire.org> Date: Thu, 29 Oct 2026 16:17:43 +0000 (UTC) From: Michael Tremer Precedence: list List-Id: List-Subscribe: , List-Unsubscribe: , List-Post: List-Help: Sender: Mail-Followup-To: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree". The branch, master has been updated via 7d93a465862e5b87d0de299053f27dc1e79f77b6 (commit) via 2d1806e8005e1a70f7bb5e9e82a3dabb0b29f533 (commit) via 5e9f5539a31beadeec9d4911af9cecc10a158899 (commit) via 3d496523670917ee57d122ffefdfe9439ddcfe1f (commit) via c62f5a4d71281597e791fd046f01e16a377c9a2e (commit) via 584f52a5d00d2e8ad3ca6867c2500b1ffa1cbd5b (commit) via 9516bcc24dbe912e171610d9a3e9bc358809405f (commit) via eae8f5d42e2b36ffab0b07f7545dbe65513bd6b3 (commit) via a5767c6fad62499a183787b3f5c81f4016643772 (commit) from d37aca7cfd4c62d04b4033e5a0a3a8bad9ce510e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7d93a465862e5b87d0de299053f27dc1e79f77b6 Author: Adolf Belka Date: Sun Oct 25 21:49:08 2026 +0100 update.sh: Fix bug14615 - remove old 5.x plugins Fixes: Bug14615 Signed-off-by: Adolf Belka Signed-off-by: Michael Tremer commit 2d1806e8005e1a70f7bb5e9e82a3dabb0b29f533 Author: Michael Tremer Date: Thu Oct 29 16:06:48 2026 +0000 core205: Regenerate the DHCP configuration The event handlers in dhcpd.conf have changed, but the file is only written when the settings are saved in the web user interface. Existing installations would keep calling dhcp-lease with wrong arguments. dhcp.cgi now rebuilds the configuration when it is run from the command line and the update does that. The init script is shipped, too. Signed-off-by: Michael Tremer commit 5e9f5539a31beadeec9d4911af9cecc10a158899 Author: Michael Tremer Date: Thu Oct 29 16:06:48 2026 +0000 knot-resolver: Answer leases for all zones and any subnet size The reverse zones were calculated by rounding the prefix down and then raising two to the power of the difference, which is a fraction for every prefix that is not a multiple of eight. For example, nothing was registered for a /23 or a /25. This patch rounds up to the next /8, /16 or /24 instead, and always registers at least one zone. Furthermore, the lookup was only enabled for GREEN and BLUE. It is now enabled for every zone that has DHCP enabled. Signed-off-by: Michael Tremer commit 3d496523670917ee57d122ffefdfe9439ddcfe1f Author: Michael Tremer Date: Thu Oct 29 11:12:17 2026 +0000 dhcp: Clean up the leases database after starting dhcpd Leases that have expired while dhcpd was not running (e.g. during a restart after a configuration change) never trigger "on expiry" and would stay in the DNS database forever. Signed-off-by: Michael Tremer commit c62f5a4d71281597e791fd046f01e16a377c9a2e Author: Michael Tremer Date: Thu Oct 29 11:12:17 2026 +0000 dhcp-lease: Replace conflicting entries and harden the script The hostname is unique in the database, but we only handled conflicts on the address. If a client moved to a new address, the insert failed and the old address was kept until it expired, but sqlite3's exit code was ignored so that dhcpd never noticed. This patch replaces any conflicting entry, passes errors on to the caller, rejects unknown actions and validates the address and the domain name before they are passed to sqlite3. dhcpd runs as root, but the resolver opens the database as an unprivileged user. Therefore the owner of the database files is set after every change. A new cleanup action removes all entries for addresses that have neither an active lease nor a static assignment. dhcpd does not run "on expiry" for leases that expire while it is not running. Signed-off-by: Michael Tremer commit 584f52a5d00d2e8ad3ca6867c2500b1ffa1cbd5b Author: Michael Tremer Date: Thu Oct 29 11:12:17 2026 +0000 knot-resolver: Send NXDOMAIN or NODATA for unknown leases The check whether there is an answer was always true, because answer is a table, so we never sent NXDOMAIN and queries for unknown names or other record types were passed on to the upstream servers. This patch looks up the name regardless of the query type, answers with NODATA if the name exists, but not for this type, and sends NXDOMAIN if the name is unknown. Signed-off-by: Michael Tremer commit 9516bcc24dbe912e171610d9a3e9bc358809405f Author: Michael Tremer Date: Thu Oct 29 11:12:17 2026 +0000 knot-resolver: Install the leases schema with mode 644 The mode 6444 also set the setuid and setgid bits on a file that is only ever read by sqlite3. Signed-off-by: Michael Tremer commit eae8f5d42e2b36ffab0b07f7545dbe65513bd6b3 Author: Michael Tremer Date: Thu Oct 29 11:06:00 2026 +0000 dhcp: Fix the syntax of the event handlers dhcpd does not know the != operator in conditions, so the check whether a hostname is known was invalid. Besides, the variable always contained the "HOSTNAME=" prefix and therefore was never empty. This patch checks the hostname itself using "not (... = ...)" and only adds the prefix when calling dhcp-lease. Signed-off-by: Michael Tremer commit a5767c6fad62499a183787b3f5c81f4016643772 Author: Michael Tremer Date: Thu Oct 29 10:20:40 2026 +0000 dhcp: Add a hostname to fixed leases The remark field of a fixed lease has always been used to store the hostname of the client. Since this is not part of the generated dhcpd.conf, static leases never made it into the database that is used by the DNS resolver, because the client does not necessarily send a hostname. This patch renames that field to hostname, validates it and writes it as "option host-name" to the host declaration so that the on commit handler will pick it up. A new remark field is added which is stored base64-encoded so that it may contain arbitrary text. Existing entries do not need to be migrated. Signed-off-by: Michael Tremer ----------------------------------------------------------------------- Summary of changes: config/knot-resolver/config.lua | 70 ++++++++---------- config/knot-resolver/dhcp-lease | 116 +++++++++++++++++++++++++++--- config/knot-resolver/leases.lua | 38 ++++++---- config/rootfiles/core/205/filelists/files | 1 + config/rootfiles/core/205/update.sh | 7 ++ html/cgi-bin/dhcp.cgi | 69 +++++++++++------- lfs/knot-resolver | 2 +- src/initscripts/system/dhcp | 3 + 8 files changed, 213 insertions(+), 93 deletions(-) Difference in files: diff --git a/config/knot-resolver/config.lua b/config/knot-resolver/config.lua index ba93fc3116..e640c593f4 100644 --- a/config/knot-resolver/config.lua +++ b/config/knot-resolver/config.lua @@ -143,16 +143,11 @@ local function reverse_zones(address, netmask) return end - -- Round to to the nearest /8, /16, /24 or /32 - local p = math.floor(prefix / 8) * 8 - - -- Fail if we would be generating all /8 zones - if not p then - return - end + -- Round up to the next /8, /16 or /24 (smaller networks end up in their /24) + local p = math.min(math.ceil(prefix / 8) * 8, 24) -- Determine how many zones we need - local n = 2 ^ (p - prefix) + local n = math.max(2 ^ (p - prefix), 1) local zones = {} @@ -408,40 +403,33 @@ function config.load_leases() -- Load the leases module modules.load("leases") - -- Enabled on GREEN? - if settings["ENABLE_GREEN"] == "on" then - policy.add( - policy.suffix(leases.answer(), { - todname(settings["DOMAIN_NAME_GREEN"]) - }) - ) - - -- Fetch subnet - local netaddr = ethernet["GREEN_NETADDRESS"] - local netmask = ethernet["GREEN_NETMASK"] - - -- Reverse lookup - policy.add( - policy.suffix(leases.answer(), reverse_zones(netaddr, netmask)) - ) - end + -- Enable the lookup for all zones that have DHCP enabled + for key, value in pairs(settings) do + local zone = key:match("^ENABLE_(.+)$") - -- Enabled on BLUE? - if settings["ENABLE_BLUE"] == "on" then - policy.add( - policy.suffix(leases.answer(), { - todname(settings["DOMAIN_NAME_BLUE"]) - }) - ) - - -- Fetch subnet - local netaddr = ethernet["BLUE_NETADDRESS"] - local netmask = ethernet["BLUE_NETMASK"] - - -- Reverse lookup - policy.add( - policy.suffix(leases.answer(), reverse_zones(netaddr, netmask)) - ) + if zone and value == "on" then + local domain = settings["DOMAIN_NAME_" .. zone] + + -- Forward lookup + if domain and domain ~= "" then + policy.add( + policy.suffix(leases.answer(), { todname(domain) }) + ) + end + + -- Fetch subnet + local netaddr = ethernet[zone .. "_NETADDRESS"] + local netmask = ethernet[zone .. "_NETMASK"] + + -- Reverse lookup + if netaddr and netmask then + local zones = reverse_zones(netaddr, netmask) + + if zones then + policy.add(policy.suffix(leases.answer(), zones)) + end + end + end end end diff --git a/config/knot-resolver/dhcp-lease b/config/knot-resolver/dhcp-lease index 5dcfeaa7ea..4c285a551d 100644 --- a/config/knot-resolver/dhcp-lease +++ b/config/knot-resolver/dhcp-lease @@ -1,6 +1,51 @@ #!/bin/bash readonly DB_PATH="/var/lib/knot-resolver/leases.db" +readonly DB_USER="knot-resolver" + +readonly DHCPD_CONF="/var/ipfire/dhcp/dhcpd.conf" +readonly DHCPD_CONF_LOCAL="/var/ipfire/dhcp/dhcpd.conf.local" +readonly DHCPD_LEASES="/var/state/dhcp/dhcpd.leases" + +# dhcpd runs as root, but the resolver opens the database as an +# unprivileged user and needs to be able to access all files of SQLite +fix_permissions() { + chown "${DB_USER}:${DB_USER}" \ + "${DB_PATH}" "${DB_PATH}-wal" "${DB_PATH}-shm" 2>/dev/null + + return 0 +} + +# Prints all addresses that are currently in use, either because they have +# an active lease or because they are assigned statically +active_addresses() { + local now="$(date -u "+%Y/%m/%d %H:%M:%S")" + + # Dynamic leases (the last entry for an address wins) + if [ -r "${DHCPD_LEASES}" ]; then + awk -v "now=${now}" ' + $1 == "lease" { address = $2; active = 0; ends = "" } + $1 == "binding" && $2 == "state" { active = ($3 == "active;") } + $1 == "ends" { + ends = ($2 == "never;") ? "never" : $3 " " $4 + sub(/;$/, "", ends) + } + $1 == "}" && address != "" { + state[address] = active && (ends == "never" || ends > now) + address = "" + } + END { + for (address in state) + if (state[address]) + print address + } + ' "${DHCPD_LEASES}" + fi + + # Static leases + sed -n -e 's/^[[:space:]]*fixed-address[[:space:]]\+\([0-9.]\+\);.*$/\1/p' \ + "${DHCPD_CONF}" "${DHCPD_CONF_LOCAL}" 2>/dev/null +} main() { # Create the database if it does not exist @@ -10,6 +55,8 @@ main() { echo "${0}: Failed to create database" >&2 return 1 fi + + fix_permissions fi local action="${1}" @@ -50,6 +97,16 @@ main() { echo "${0}: Missing DOMAINNAME=" >&2 return 2 + # Validate the address + elif ! [[ ${address} =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; then + echo "${0}: Invalid address" >&2 + return 2 + + # Validate the domain name + elif ! [[ ${domainname} =~ ^[A-Za-z0-9_.-]+$ ]]; then + echo "${0}: Invalid domain name" >&2 + return 2 + # Validate the hostname elif ! [[ ${hostname} =~ ^[A-Za-z0-9_-]{1,63}$ ]]; then echo "${0}: Invalid hostname" >&2 @@ -62,13 +119,15 @@ main() { # Make the hostname lowercase hostname="${hostname,,}" - sqlite3 "${DB_PATH}" <<-EOF + # If the hostname is already in use by another address (e.g. + # because the client has moved), the old entry is replaced. + if ! sqlite3 "${DB_PATH}" <<-EOF -- Set parameters .parameter set :address '${address}' .parameter set :hostname '${hostname}' -- Run statement - INSERT INTO + INSERT OR REPLACE INTO leases ( address, @@ -78,14 +137,12 @@ main() { ( :address, :hostname - ) - ON CONFLICT - ( - address - ) - DO UPDATE SET - hostname = excluded.hostname; + ); EOF + then + echo "${0}: Failed to store the lease" >&2 + return 1 + fi ;; release|expiry) @@ -109,7 +166,7 @@ main() { return 2 fi - sqlite3 "${DB_PATH}" <<-EOF + if ! sqlite3 "${DB_PATH}" <<-EOF -- Set parameters .parameter set :address '${address}' @@ -119,8 +176,47 @@ main() { WHERE address = :address; EOF + then + echo "${0}: Failed to remove the lease" >&2 + return 1 + fi + ;; + + # Removes all entries for addresses which are no longer in use. This + # is necessary because dhcpd does not run any "on expiry" events for + # leases that have expired while it was not running. + cleanup) + local address + local statements="" + + while read -r address; do + [[ ${address} =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]] || continue + + statements+="INSERT INTO keep(address) VALUES('${address}');"$'\n' + done < <(active_addresses) + + if ! sqlite3 "${DB_PATH}" <<-EOF + CREATE TEMP TABLE keep(address TEXT PRIMARY KEY); + ${statements} + DELETE FROM + leases + WHERE + address NOT IN (SELECT address FROM keep); + EOF + then + echo "${0}: Failed to clean up the database" >&2 + return 1 + fi + ;; + + *) + echo "${0}: Unknown action: ${action}" >&2 + return 2 + ;; esac + fix_permissions + return 0 } diff --git a/config/knot-resolver/leases.lua b/config/knot-resolver/leases.lua index 186dfe4d6f..d1c174103d 100644 --- a/config/knot-resolver/leases.lua +++ b/config/knot-resolver/leases.lua @@ -129,29 +129,37 @@ function M.answer() ) local answer = {} + local exists = false - -- Is this a forward lookup? - if qtype == kres.type.A then - -- Perform a forward lookup - local address = lookup_fwd(qname) + -- Is this a reverse lookup? + if qname:match("%.in%-addr%.arpa%.$") then + local hostname = lookup_rev(qname) - if address then - answer[qtype] = { rdata = address, ttl = TTL } + if hostname then + exists = true + + if qtype == kres.type.PTR then + answer[qtype] = { rdata = hostname, ttl = TTL } + end end - -- Or is this a reverse lookup? - elseif qtype == kres.type.PTR then - -- Perform a reverse lookup - local hostname = lookup_rev(qname) + -- Otherwise this is a forward lookup + else + local address = lookup_fwd(qname) - if hostname then - answer[qtype] = { rdata = hostname, ttl = TTL } + if address then + exists = true + + if qtype == kres.type.A then + answer[qtype] = { rdata = address, ttl = TTL } + end end end - -- If we have an answer, use the policy module to send it - if answer then - answer = policy.ANSWER(answer) + -- If the name exists, we send the answer (or NODATA if we have nothing + -- for this query type) + if exists then + answer = policy.ANSWER(answer, true) -- Otherwise we send NXDOMAIN else diff --git a/config/rootfiles/core/205/filelists/files b/config/rootfiles/core/205/filelists/files index adac1bbf73..6f43b341d9 100644 --- a/config/rootfiles/core/205/filelists/files +++ b/config/rootfiles/core/205/filelists/files @@ -1,4 +1,5 @@ etc/rc.d/init.d/console +etc/rc.d/init.d/dhcp etc/rc.d/init.d/firewall etc/rc.d/init.d/swconfig etc/rc.d/rcsysinit.d/S73swconfig diff --git a/config/rootfiles/core/205/update.sh b/config/rootfiles/core/205/update.sh index 88281e890c..81f019f12a 100644 --- a/config/rootfiles/core/205/update.sh +++ b/config/rootfiles/core/205/update.sh @@ -59,6 +59,10 @@ sed -i /var/ipfire/main/settings \ rm -vf \ /usr/lib/libboost*.so.1.90.0 +# Remove old strongswan-5.x plugin conf files +rm -vf \ + /etc/strongswan.d/charon/{aes,curve25519,des,gmp,md5,pkcs12,sha1,sha2}.conf + # update linker config ldconfig @@ -77,6 +81,9 @@ gpgconf --kill all # Restart the firewall /etc/init.d/firewall restart +# Regenerate the DHCP configuration because the event handlers have changed +sudo -u nobody /srv/web/ipfire/cgi-bin/dhcp.cgi /dev/null + # Start services /etc/init.d/knot-resolver restart /etc/init.d/openvpn-rw restart diff --git a/html/cgi-bin/dhcp.cgi b/html/cgi-bin/dhcp.cgi index a8e288df34..6f90bebf18 100644 --- a/html/cgi-bin/dhcp.cgi +++ b/html/cgi-bin/dhcp.cgi @@ -20,6 +20,7 @@ ############################################################################### use strict; +use MIME::Base64; use Time::Local; use experimental 'smartmatch'; @@ -92,12 +93,13 @@ $dhcpsettings{'FIX_ENABLED'} = 'off'; $dhcpsettings{'FIX_NEXTADDR'} = ''; $dhcpsettings{'FIX_FILENAME'} = ''; $dhcpsettings{'FIX_ROOTPATH'} = ''; +$dhcpsettings{'FIX_HOSTNAME'} = ''; $dhcpsettings{'FIX_REMARK'} = ''; $dhcpsettings{'ACTION'} = ''; $dhcpsettings{'KEY1'} = ''; $dhcpsettings{'KEY2'} = ''; @nosaved=('FIX_MAC','FIX_ADDR','FIX_ENABLED','FIX_NEXTADDR', - 'FIX_FILENAME','FIX_ROOTPATH','FIX_REMARK'); + 'FIX_FILENAME','FIX_ROOTPATH','FIX_HOSTNAME','FIX_REMARK'); $dhcpsettings{'ADVOPT_ENABLED'} = ''; $dhcpsettings{'ADVOPT_NAME'} = ''; @@ -131,6 +133,13 @@ open(FILE, "$filename2") or die 'Unable to open fixed leases file.'; our @current2 = ; close(FILE); +# Regenerate the configuration when this script is run from the command line (e.g. by an update) +if (!defined $ENV{'REQUEST_METHOD'}) { + &General::readhash($setting, \%dhcpsettings); + &buildconf; + exit 0; +} + # Open and read-in file which contains the list of allowed advanced options. open(FILE, $filename3) or die "Could not open $filename3. $!\n"; @@ -425,6 +434,9 @@ if ($dhcpsettings{'ACTION'} eq _('Add').'2') { if ($dhcpsettings{'FIX_NEXTADDR'}) { unless(&Network::check_ip_address($dhcpsettings{'FIX_NEXTADDR'})) { $errormessage = _('Invalid Fixed IP Address'); } } + if ($dhcpsettings{'FIX_HOSTNAME'}) { + unless(&Network::check_hostname($dhcpsettings{'FIX_HOSTNAME'})) { $errormessage = _('Invalid hostname.'); } + } my $key = 0; CHECK:foreach my $line (@current2) { @@ -448,12 +460,14 @@ if ($dhcpsettings{'ACTION'} eq _('Add').'2') { } unless ($errormessage) { - $dhcpsettings{'FIX_REMARK'} = &Header::escape($dhcpsettings{'FIX_REMARK'}); + $dhcpsettings{'FIX_HOSTNAME'} = &Header::escape($dhcpsettings{'FIX_HOSTNAME'}); + # The remark is free text and is therefore stored base64 encoded + my $remark = &encode_base64($dhcpsettings{'FIX_REMARK'}, ''); $dhcpsettings{'FIX_NEXTADDR'} = &Header::escape($dhcpsettings{'FIX_NEXTADDR'}); $dhcpsettings{'FIX_FILENAME'} = &Header::escape($dhcpsettings{'FIX_FILENAME'}); $dhcpsettings{'FIX_ROOTPATH'} = &Header::escape($dhcpsettings{'FIX_ROOTPATH'}); if ($dhcpsettings{'KEY2'} eq '') { #add or edit ? - unshift (@current2, "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},$dhcpsettings{'FIX_ENABLED'},$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},$dhcpsettings{'FIX_ROOTPATH'},$dhcpsettings{'FIX_REMARK'}\n"); + unshift (@current2, "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},$dhcpsettings{'FIX_ENABLED'},$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},$dhcpsettings{'FIX_ROOTPATH'},$dhcpsettings{'FIX_HOSTNAME'},$remark\n"); open(FILE, ">$filename2") or die 'Unable to open fixed lease file.'; print FILE @current2; close(FILE); @@ -462,7 +476,7 @@ if ($dhcpsettings{'ACTION'} eq _('Add').'2') { # Enter edit mode $dhcpsettings{'KEY2'} = 0; } else { - @current2[$dhcpsettings{'KEY2'}] = "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},$dhcpsettings{'FIX_ENABLED'},$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},$dhcpsettings{'FIX_ROOTPATH'},$dhcpsettings{'FIX_REMARK'}\n"; + @current2[$dhcpsettings{'KEY2'}] = "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},$dhcpsettings{'FIX_ENABLED'},$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},$dhcpsettings{'FIX_ROOTPATH'},$dhcpsettings{'FIX_HOSTNAME'},$remark\n"; $dhcpsettings{'KEY2'} = ''; # End edit mode &General::log(_('Fixed IP Lease Modified')); @@ -482,7 +496,7 @@ if ($dhcpsettings{'ACTION_ALL'} eq '+') { my $ip=$1; my $mac=$2; if (!grep (/$2/,@current2)) { - unshift (@current2, "$mac,$ip,on,,,,imported\n"); + unshift (@current2, "$mac,$ip,on,,,,," . &encode_base64("imported", "") . "\n"); $news++; } } @@ -507,7 +521,8 @@ if ($dhcpsettings{'ACTION'} eq _('Edit').'2') { $dhcpsettings{'FIX_NEXTADDR'}=$temp[3]; $dhcpsettings{'FIX_FILENAME'}=$temp[4]; $dhcpsettings{'FIX_ROOTPATH'}=$temp[5]; - $dhcpsettings{'FIX_REMARK'}=$temp[6]; + $dhcpsettings{'FIX_HOSTNAME'}=$temp[6]; + $dhcpsettings{'FIX_REMARK'}=&decode_base64($temp[7] // ''); } if ($dhcpsettings{'ACTION'} eq _('Remove').'2') { @@ -957,8 +972,11 @@ print < @{[ _('IP Address:') ]} * + @{[ _('Hostname:') ]} + + @{[ _('Remark:') ]} - + @{[ _('Enabled:') ]} @@ -1009,8 +1027,9 @@ END print < - @{[ _('MAC Address') ]} - @{[ _('IP Address') ]} + @{[ _('MAC Address') ]} + @{[ _('IP Address') ]} + @{[ _('Hostname') ]} @{[ _('Remark') ]} next-server filename @@ -1110,6 +1129,7 @@ foreach my $line (@current2) { $TAG2$temp[0]$TAG3 $TAG0$temp[1]$TAG1 $temp[6]  +@{[ &Header::escape(&decode_base64($temp[7] // '')) ]}  $temp[3]  $temp[4]  $temp[5]  @@ -1310,7 +1330,7 @@ END print <$entries{$key}->{IPADDR} $entries{$key}->{ETHER} -$hostname_print +$hostname_print $entries{$key}->{endtime_print} END ; @@ -1318,7 +1338,7 @@ END print <$entries{$key}->{IPADDR} $entries{$key}->{ETHER} -$hostname_print +$hostname_print $entries{$key}->{endtime_print} END ; @@ -1419,9 +1439,9 @@ sub sortcurrent2 #Use an associative array (%entries) foreach my $line (@current2) { - chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK) + chomp( $line); #remove newline because can be on field 5 or 6 (addition of HOSTNAME and REMARK) my @temp = split (',',$line); - my @record = ('FETHER',$temp[0],'FIPADDR',$temp[1],'DATA',join(',',@temp[2..6])); + my @record = ('FETHER',$temp[0],'FIPADDR',$temp[1],'DATA',join(',',@temp[2..7])); my $record = {}; # create a reference to empty hash %{$record} = @record; # populate that hash with @record # use combination of ether & IP as key to allow duplicates in either but not both @@ -1564,17 +1584,14 @@ on commit { "ADDRESS=", binary-to-ascii(10, 8, ".", leased-address) ); - set ClientHostName = concat( - "HOSTNAME=", - pick-first-value(option host-name, config-option-host-name, client-name, "") - ); + set ClientHostName = pick-first-value(option host-name, config-option-host-name, client-name, ""); set ClientDomainName = concat( "DOMAINNAME=", pick-first-value(config-option domain-name, "") ); - if (ClientHostName != "") { - execute("/usr/sbin/dhcp-lease", "commit", ClientAddress, ClientHostName, ClientDomainName); + if not (ClientHostName = "") { + execute("/usr/sbin/dhcp-lease", "commit", ClientAddress, concat("HOSTNAME=", ClientHostName), ClientDomainName); } } @@ -1583,17 +1600,14 @@ on release { "ADDRESS=", binary-to-ascii(10, 8, ".", leased-address) ); - set ClientHostName = concat( - "HOSTNAME=", - pick-first-value(option host-name, config-option-host-name, client-name, "") - ); + set ClientHostName = pick-first-value(option host-name, config-option-host-name, client-name, ""); set ClientDomainName = concat( "DOMAINNAME=", pick-first-value(config-option domain-name, "") ); - if (ClientHostName != "") { - execute("/usr/sbin/dhcp-lease", "release", ClientAddress, ClientHostName, ClientDomainName); + if not (ClientHostName = "") { + execute("/usr/sbin/dhcp-lease", "release", ClientAddress, concat("HOSTNAME=", ClientHostName), ClientDomainName); } } @@ -1614,10 +1628,13 @@ EOF chomp($line); my @temp = split(/\,/,$line); if ($temp[2] eq "on") { - print FILE "\nhost fix$key # $temp[6]\n"; + my $remark = &decode_base64($temp[7] // ""); + $remark =~ s/[\r\n]+/ /g; + print FILE "\nhost fix$key # $remark\n"; print FILE "{\n"; print FILE "\thardware ethernet $temp[0];\n"; print FILE "\tfixed-address $temp[1];\n"; + print FILE "\toption host-name \"$temp[6]\";\n" if ($temp[6] && &Network::check_hostname($temp[6])); print FILE "\tnext-server $temp[3];\n" if ($temp[3]); print FILE "\tfilename \"" . &EscapeFilename($temp[4]) . "\";\n" if ($temp[4]); print FILE "\toption root-path \"$temp[5]\";\n" if ($temp[5]); diff --git a/lfs/knot-resolver b/lfs/knot-resolver index 3f35a9f2cf..0d3e0d2d01 100644 --- a/lfs/knot-resolver +++ b/lfs/knot-resolver @@ -104,7 +104,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) /usr/lib/knot-resolver/kres_modules/leases.lua # Install the leases schema - install -v -m 6444 $(DIR_SRC)/config/knot-resolver/leases.schema \ + install -v -m 644 $(DIR_SRC)/config/knot-resolver/leases.schema \ /usr/lib/knot-resolver/leases.schema # Create the leases database diff --git a/src/initscripts/system/dhcp b/src/initscripts/system/dhcp index 735f7c57bb..d83b06c1db 100644 --- a/src/initscripts/system/dhcp +++ b/src/initscripts/system/dhcp @@ -55,6 +55,9 @@ case "$1" in loadproc -f /usr/sbin/dhcpd -q ${LISTEN_INTERFACES} (sleep 5 && chmod 644 /var/run/dhcpd.pid) & # Fix because silly dhcpd creates its pid with mode 640 + + # Remove leases from the DNS database that have expired while dhcpd was not running + (sleep 5 && /usr/sbin/dhcp-lease cleanup) & ;; stop) hooks/post-receive -- IPFire 2.x development tree