Commit Graph
234 Commits
Author SHA1 Message Date
Yu Watanabe 90481c0b1b tree-wide: add missing assertions
Found by coccinelle.
2026-08-18 06:30:10 +09:00
Zbigniew Jędrzejewski-Szmek 8975c5c1cf Add a "declarative program header" and introspection of options and verbs (#43152) 2026-08-14 11:52:42 +02:00
Yu Watanabe 8f4cd7de43 resolvectl: fix query option handling and resolvconf input errors (#43370) 2026-08-14 00:35:58 +09:00
Zbigniew Jędrzejewski-Szmek 94af9a8b40 verbs: wrap abstract too
So far there's only one multi-line abstract. But as pointed out in the
review, it's silly to handle footer but not the abstract.

help_abstract() is not reused because it only works with one-line
abstracts. (It always prints an empty line to separate paragraphs.)
So the formatting is done anew in print_wrapped(). I think this is OK,
since it's all very simple. After everything has been converted to
COMMAND() and its helpers, help_abstract() and the sister functions will
become unused and can be dropped then.
2026-08-13 13:52:35 +02:00
Zbigniew Jędrzejewski-Szmek 7670c20c6e verbs: add PagerFlags pointer to all CommandDescription's
Before this series, many help() functions opened the pager. This got lost
in the translation. Starting the pager requires access to arg_pager_flags.
While we could pipe this through in case when command_print_help() is
called directly, but this hard in the case when verb_help_auto() or
VERB_COMMON_HELP_AUTO/VERB_COMMON_HELP_AUTO_HIDDEN are used. Let's instead
extend the (const static) CommandDescription structure with a pointer to
the arg_pager_flags variable. This restores the pager functionality in a
uniform fashion with a one-line change in the individual binaries.
2026-08-13 13:46:08 +02:00
Zbigniew Jędrzejewski-Szmek 8a14181f55 resolvectl: separate systemd-resolve in introspection data
Previously, the systemd-resolve compat alias was described in the same
CommandDescription structure and resolvectl. But they have different
option sets, so this doesn't really work. The alias is deprecated, so
describe it as such in the abstract, but give it a separate entry.

$ build/resolvectl --introspect-cli
{
  "mediaType": "application/vnd.io.systemd.cli-introspection-0",
  "commands": [
    {
      "names": [ "resolvconf" ],
      "abstract": [
        "Register DNS server and domain configuration with systemd-resolved."
      ],
      ...
    },
    {
      "names": [ "resolvectl" ],
      "abstract": [
        "Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services."
      ],
      ...
    },
    {
      "names": [ "systemd-resolve" ],
      "abstract": [
        "Send control commands to the network name resolution manager, or\nresolve domain names, IPv4 and IPv6 addresses, DNS records, and services.\n\nThis command is deprecated. Use resolvectl.1 instead."
      ],
      ...
    }
  ]
}
2026-08-13 13:23:05 +02:00
Zbigniew Jędrzejewski-Szmek 1a54ce154c various: add --introspect-cli 2026-08-13 13:23:05 +02:00
Zbigniew Jędrzejewski-Szmek df03655bc5 resolvectl: convert to VERB_COMMAND 2026-08-13 13:23:05 +02:00
Zbigniew Jędrzejewski-Szmek 580489eeec resolvectl: drop --help for systemd-resolve
The rename was done in v239. We generally don't document obsolete
interfaces, so let's just drop the (very nice) --help that we have here.
2026-08-13 13:23:05 +02:00
dongshengyuan e7223f2ab2 resolvectl: reject --raw for regular lookups
--raw only affects ResolveRecord output. Without --type= or an
RFC4501 dns: URI, query takes the ResolveHostname/ResolveAddress
paths, where --raw was silently ignored.

Reproducer:

  build/resolvectl --raw query localhost

Before:

  The command exited successfully and printed regular text output,
  such as:

    localhost: 127.0.0.1

After:

  The command fails before issuing a lookup:

    --raw may only be combined with --type= or dns: URIs.

Follow-up for: 05ea7e87b6
2026-08-13 17:40:49 +08:00
dongshengyuan e021a64391 resolvectl: avoid TXT lookup for plain SRV service queries
The service verb documents the one- and two-argument forms as
SRV lookups. They should not request TXT records by default.
Only the three-argument DNS-SD form should request TXT metadata.

Reproducer:

  Run resolvectl service _mysvc._tcp signed.test in the
  TEST-75-RESOLVED environment, where signed.test contains:

    _mysvc._tcp SRV 10 5 1234 myservice
    _mysvc._tcp TXT "This is TXT for myservice"
    myservice A 10.0.0.20

Before:

  resolvectl service _mysvc._tcp signed.test printed TXT data
  for the plain SRV form:

    _mysvc._tcp/signed.test: myservice.signed.test:1234 [priority=10, weight=5]
                             10.0.0.20
                             fd00:dead:beef:cafe::17
                             This is TXT for myservice

After:

  The plain SRV form suppresses TXT data. The DNS-SD form still
  shows it:

    resolvectl service '' _mysvc._tcp signed.test

Follow-up for: a7a4c60a25
2026-08-13 17:40:49 +08:00
dongshengyuan 060b0d2f70 resolvectl: reject tlsa without a domain
The tlsa command accepts an optional service family before the domain list.
When the only argument was "tcp", "udp", or "sctp", we consumed it as the
family and returned success without issuing any query.

Reproducer:

  build/resolvectl tlsa tcp

Before: the command printed nothing and exited with status 0.

Follow-up for: ebbc70e511
2026-08-13 09:02:52 +08:00
dongshengyuan 32b3aabfe7 resolvectl: render DNS errors as JSON
When --json is requested, resolution errors returned by resolved still went
through text logging. That made scripts parse stderr even though the
varlink error already carried structured fields such as rcode and EDE.

Add a small JSON error dumper for resolvectl query errors. It outputs the
queried name and varlink error id alongside the original varlink parameters
so DNSError and DNSSECValidationFailed expose rcode, extendedDNSErrorCode,
extendedDNSErrorMessage, queryString, and result without duplicating the
schema in resolvectl.

Keep non-JSON text output and silent warn_missing NXDOMAIN handling
unchanged. Document the JSON resolution error object in resolvectl(1),
including the distinction between resolved errors and local invocation or
connection errors.

Closes #42904
2026-08-08 08:33:31 +09:00
dongshengyuan 05ea7e87b6 resolvectl: support JSON output for openpgp and tlsa
The openpgp and tlsa verbs rejected --json= even though they
already determine the RR type they query. Allow JSON output for
these shortcut commands.

Accept matching explicit --type= values as well, but reject
mismatched types so openpgp only queries OPENPGPKEY records and
tlsa only queries TLSA records.

Refuse unauthenticated key records in JSON format so scripts do
not accidentally consume cryptographic DNS data that would only
produce a warning in human-readable output.

Fixes #43245
2026-08-04 08:08:33 +09:00
Yu Watanabe 661ab8b6fd tree-wide: drop DLOPEN_FOO() macros
Since 4c0d8d9673, most dlopen notes are
set at the beginning of the executables. Let's manage all dlopen notes
there, rather than setting them where dlopen is called.

Note that the only exceptions are the LIBBPF_NOTE for networkd and
nsresource. Since dlopen_bpf() is wrapped in an `#if` guard, the notes
are instead set within the corresponding functionality.

As a result, the DLOPEN_FOO() wrapper macros are no longer needed and
can be dropped completely.
2026-07-18 04:56:32 +09:00
Yu Watanabe 4c0d8d9673 tree-wide: embed dlopen notes into individual executables
Previously, when a library was dynamically loaded via a helper function
inside libsystemd-shared.so, the resulting dlopen ELF note was not
propagated to the invoking executable's ELF metadata.

This commit explicitly annotates each executable with the relevant
dlopen ELF notes for any optional dependencies it might potentially
load. This ensures that package managers and build systems can properly
discover runtime dependencies that are triggered indirectly.
2026-07-10 16:35:19 +09:00
dongshengyuan 7808a0c541 resolvectl: fix JSON reply cleanup in varlink_dump_dns_configuration
varlink_call_and_log() does not hand out a new reference for the reply
object, so the caller should not unref it. The _cleanup_(sd_json_variant_unrefp)
on reply was therefore wrong from the start.

The original TAKE_PTR(reply) was working around this incorrect cleanup
by preventing it from firing, but that left reply's refcount one too
high after sd_json_variant_ref(v) incremented the parent's count.

Fix by dropping _cleanup_(sd_json_variant_unrefp) from the reply
variable declaration entirely, as suggested by Lennart Poettering.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-06-30 17:26:41 +08:00
Nick Rosbrook fa6fe468f4 resolvectl: use varlink instead of dbus for ResolveService 2026-06-26 16:03:18 -04:00
Nick Rosbrook cfac7ec169 resolvectl: use varlink instead of dbus for ResolveRecord 2026-06-26 16:03:18 -04:00
Nick Rosbrook 5ff17fb750 resolvectl: use varlink instead of dbus for ResolveAddress 2026-06-26 16:03:18 -04:00
Nick Rosbrook 35d611622a resolvectl: use varlink instead of dbus for ResolveHostname 2026-06-26 16:03:18 -04:00
Nick Rosbrook c5f08a2e5c json-util: generalize json_dispatch_address_family
There are several places where address family is dispatched from JSON,
so take json_dispatch_address_family from networkd and put it in
json-util.c.

Update the all instances in the tree to use this new function, adding
SD_JSON_RELAX to the dispatch flags if AF_UNSPEC should be allowed
in that case.
2026-06-26 09:12:10 -04:00
Zbigniew Jędrzejewski-Szmek 39a3647539 tree-wide: get rid of old dispatch_verb
Also rename dispatch_verb_with_args to dispatch_verb.
2026-05-16 18:37:10 +02:00
Zbigniew Jędrzejewski-Szmek 88d7e44392 Add json_variant_unref_and_replace and use it where appropriate
JSON_VARIANT_REPLACE is similar, but doesn't try to nullify the second
arg, so it can be used with an inline expression.
2026-05-08 11:36:43 +02:00
Zbigniew Jędrzejewski-Szmek 7cea71e4c1 resolvectl: convert to OPTION and VERB macros
Use OPTION_NAMESPACE() to keep the resolvectl and systemd-resolve
option sets separate. The resolvconf-compat path (resolvconf
invocation) keeps its own getopt-based parsing.

--help output has the expected changes to formatting. Synopis
for [status] is now shows that the verb is optional.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 18:39:32 +02:00
Zbigniew Jędrzejewski-Szmek d865863929 resolvectl: move verb implementations to match order in --help 2026-05-07 18:39:04 +02:00
Zbigniew Jędrzejewski-Szmek df24074bb5 resolvectl: move things around in --help
Move the "display options" to the end of both --help strings and then
reorder the implementation to match.
2026-05-07 18:39:02 +02:00
Zbigniew Jędrzejewski-Szmek 16c3c69be3 resolvectl: split out parse_protocol 2026-05-07 18:37:48 +02:00
Daan De Meyer 8c3f64e61f tree-wide: Load libcrypto and libssl via dlopen()
Until now OpenSSL was linked into every binary and library that needed
cryptography, pulling libcrypto (and, for resolved, libssl) into the
address space of services that never touch them at runtime. This commit
moves all OpenSSL usage behind the same dlopen helper pattern that we
already use for other optional libraries (libpam, libseccomp, libxz, …)
so libcrypto/libssl are only loaded on demand.

The bulk of the work lives in src/shared/crypto-util.{c,h} (libcrypto)
and src/shared/ssl-util.{c,h} (libssl), which replace the previous
src/shared/openssl-util.{c,h}:

 - crypto-util.{c,h} declares every libcrypto function we call via
   DLSYM_PROTOTYPE() and resolves them inside dlopen_libcrypto().

 - ssl-util.{c,h} holds the libssl-specific DLSYM_PROTOTYPEs,
   dlopen_libssl(), and the SSL_freep cleanup helper, so translation
   units that only need libcrypto do not pull in libssl declarations.

 - Callers refer to the symbols through sym_* aliases rather than the
   original names.

 - Convenience macros that used to be provided by the OpenSSL headers
   (OPENSSL_free, BN_num_bytes, the sk_TYPE_* helpers, …) are
   reimplemented as sym_* wrappers so no code path needs to fall back
   to the linker-resolved symbols.

 - All _cleanup_ helpers are redefined in terms of the sym_* variants
   (EVP_PKEY_freep, X509_freep, BIO_freep, …) so cleanup attributes
   keep working without pulling in libcrypto symbols at link time.

 - The public crypto-util.c entry points (openssl_pubkey_from_pem,
   openssl_digest_many, openssl_hmac_many, openssl_cipher_many,
   kdf_ss_derive, kdf_kb_hmac_derive, rsa_* / ecc_* helpers,
   pubkey_fingerprint, digest_and_sign, pkcs7_new, x509_fingerprint,
   openssl_extract_public_key, pkey_generate_volume_keys, the load_*
   helpers, …) now call dlopen_libcrypto() at entry before touching any
   sym_* pointer.

The call sites across the tree have been converted to call
dlopen_libcrypto()/dlopen_libssl() at the appropriate entry point
before their first sym_* use, and to use sym_* variants throughout:

 - bootctl, sbsign, measure, pcrlock, pcrextend, tpm2-setup, repart,
   cryptsetup, cryptenroll, homectl, homed, homework, keyutil,
   sysupdate, creds, import, dissect-image, pe-binary, pkcs11-util,
   pkcs7-util, tpm2-util, creds-util. resolved additionally dlopens
   libssl for DoT.

The meson build files are updated to depend on libopenssl_cflags (a
new partial dependency that exposes include paths and compile flags
only, not the linker flags) instead of libopenssl for every target that
previously linked against OpenSSL. Nothing links against libcrypto or
libssl directly anymore.

A new src/sbsign/authenticode.c hosts the Authenticode ASN.1 type
definitions that used to live inline in sbsign.c. The OpenSSL
ASN1_SEQUENCE / ASN1_CHOICE / IMPLEMENT_ASN1_FUNCTIONS macros expand to
code that references libcrypto symbols directly, so to keep this
translation unit unlinked from libcrypto we redirect ASN1_item_* to
the sym_* variants via #define and wrap the ASN1_*_it() getters (which
appear as constant function pointers in static initializers) in small
trampoline functions that forward to the sym_* pointers at runtime.

test-dlopen-so gains assertions for dlopen_libcrypto and dlopen_libssl
so the dlopen contract is exercised in CI, and the openssl-specific
test was renamed from test-openssl.c to test-crypto-util.c to match
the new header naming.
2026-04-24 06:32:42 +02:00
Zbigniew Jędrzejewski-Szmek 1008583c91 tree-wide: print error if table_print() fails
We generally want to print an error message if table_print()
fails. Add a helper function for this and use it consistently.
This does one of the three things depending on the call site:
- a no-change reformatting of the code
- change from a custom message to the generic one
- addition of the error message where previously none was printed

In the third case, the actual use impact is very small, since the
table formatting is very unlikely to fail. But if it did, we would
often return an error without any message whatsoever, which we
never want to do.
2026-04-03 13:05:03 +02:00
Zbigniew Jędrzejewski-Szmek 0ce5a8fb4e tree-wide: drop flush&check step after table printing
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.

In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
2026-04-03 13:04:40 +02:00
Zbigniew Jędrzejewski-Szmek 31ddd87da0 tree-wide: extend verbs functions with extra per-verb data parameter
We often have a pattern where the same verb function is used for
multiple actions. This leads to an antipattern where we figure out what
action needs to be taken from argv[0] multiple times: often once in
parse_argv() to figure out what options are allowed, then once again
implicitly in dispatch_verb(), and then again in the action verb itself.
Let's allow passing a parameter into the verb to simplify this.

This matches a pattern we have in conf-parser.h, where we have both
void *userdata (more global) and void *data (per-config item). Here,
I opted for uintptr_t userdata. It seems that most of the time we'll
want to just pass an enum value. This works OK with no casts. I also
tried a void* and union. In both cases, much more boilerplate is needed:
either a cast or a macro to help avoid compiler warnings. uintptr_t
seems generic enough to cover foreseeable usecases with no fuss.

This is a noop refactoring. See next commit for an example.
2026-03-18 10:28:47 +00:00
Zbigniew Jędrzejewski-Szmek cdf9951fe0 resolvectl: call all verb functions verb_* 2026-03-18 10:28:47 +00:00
Nick Rosbrook e28958315f resolvectl: include ifindex when printing link-local DNS server
Historically, resolvectl status has not included the interface
specification for DNS servers with an IPv6 link-local address, since it
is technically somewhat redundant. But, adding this extra bit of
information makes it easier to copy-and-paste to use elsewhere, etc.

For example, the previous output:

 Link 2 (enp34s0)
     Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
          Protocols: +DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
 Current DNS Server: fe80::861e:a3ff:feb1:f8e7
        DNS Servers: 192.168.1.12 192.168.1.13 fe80::861e:a3ff:feb1:f8e7
         DNS Domain: lan

now becomes:

 Link 2 (enp34s0)
     Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
          Protocols: +DefaultRoute LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
 Current DNS Server: fe80::861e:a3ff:feb1:f8e7%2
        DNS Servers: 192.168.1.12 192.168.1.13 fe80::861e:a3ff:feb1:f8e7%2
         DNS Domain: lan
2026-02-07 00:14:37 +01:00
Nick Rosbrook a4750a6612 resolvectl: add print_configuration() to consolidate status logic
There is a lot of duplication across the functions for printing global,
link, and delegate output. Since these all use a common DNSConfiguration
type now, the logic can be consolidated.

Adapt printing and format helper functions to accept a DNSConfiguration
parameter to appropriately format output. Then, add print_configuration(),
a single function that prints the appropriate status output based on the
contents of DNSConfiguration.
2026-02-03 15:07:41 -05:00
Nick Rosbrook 480ebdfddd resolvectl: consolidate JSON and regular status output paths
Now that varlink is always used for status output, consolidate the JSON
and regular status code paths. Add status_full(), which is the single
point that calls DumpDNSConfiguration, filters based on link names and
mode if needed, and prints the output in the appropriate format.

This simplifies status_ifindex(), and removes the need for a separate
status_json().
2026-02-03 15:07:41 -05:00
Nick Rosbrook 67746cd3b2 resolvectl: use varlink to report delegate status
This is an incremental commit to replacing dbus usage with varlink for
all status output.

Re-implement regular delegate status output using the DumpDNSConfiguration
varlink method. And, remove the DelegateInfo type and associated functions
which were used to map dbus properties.

Since this is the last type of status output to be switched to varlink,
lots of other code becomes dead with these changes, e.g.
read_dns_server_one(), map_dns_servers_internal(), etc., so remove those
too. Finally, status_all() no longer needs sd_bus, so drop that
parameter.
2026-02-03 15:07:41 -05:00
Nick Rosbrook d076d0f94f resolvectl: use varlink to report link status
This is an incremental commit to replacing dbus usage with varlink for
all status output.

Re-implement regular link status output using the DumpDNSConfiguration
varlink method. And, remove the LinkInfo type and associated functions
which were used to map dbus properties.
2026-02-03 15:07:41 -05:00
Nick Rosbrook a56366182e resolvectl: use varlink to report global status
This is an incremental commit to replacing dbus usage with varlink for
all status output.

Re-implement regular global status output using the DumpDNSConfiguration
varlink method. And, remove the GlobalInfo type and associated functions
which were used to map dbus properties.
2026-02-03 15:07:41 -05:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Lennart Poettering 8209f4adcd resolved: add hook api
This introduces /run/systemd/resolve.hook/ as a new directory that local
(privileged) programs can bind a Varlink socket into. If they do they'll
get a method call for each attempted resolved lookup, which they can
then either process themselves (and generate new records for, or return
errors to block stuff) or let pass so that the regular resolution is
done.

Usecase for this is primarily two things:

1. in machined we can add local resolution of machine names to their IP
   addresses, similar in fashion to nss-mymachines, but working also if
   the non-NSS interfaces to name resolution are used, i.e. the local
   DNS responder. In fact, I think we should eventually remove
   nss-mymachines from our tree, as soon as this code in resolved is
   setlled.

2. in networkd we can add local resolution of names specified in DHCP
   leases we hand out.

But beyond that there should be many other uses, for example people
could write "dns firewalls" with this if they like where they
dynamically block certain names from resolution.

Fixes: #8518
2025-11-15 07:44:24 +01:00
Yu Watanabe b1a95a3aa7 resolvectl: drop an empty line between function call and error handling
Follow-up for 0536b37629.
2025-11-10 11:02:51 +09:00
Yu Watanabe f2f89678ec resolvectl: use string table
Follow-up for 0536b37629.
2025-11-10 11:02:51 +09:00
Yu Watanabe fa05718dea resolvectl: rename STATUS_PRIVATE -> STATUS_DNS_OVER_TLS 2025-11-10 11:02:51 +09:00
Nick Rosbrook 0536b37629 resolvectl: implement --json flag for resolvectl status
Add --json support for all status commands in resolvectl by making use
of the new DumpDNSConfiguration varlink method. E.g,

$ resolvectl --json=pretty status eth0
[
	{
		"ifname" : "eth0",
		"ifindex" : 9,
		"defaultRoute" : true,
		"currentServer" : {
                        "addressString" : "10.148.181.1",
			"address" : [
				10,
				148,
				181,
				1
			],
			"family" : 2,
			"port" : 53,
			"ifindex" : 9,
			"accessible" : true
		},
		"servers" : [
			{
                                "addressString" : "10.148.181.1",
				"address" : [
					10,
					148,
					181,
					1
				],
				"family" : 2,
				"port" : 53,
				"ifindex" : 9,
				"accessible" : true
			}
		],
		"searchDomains" : [
			{
				"name" : "local",
				"routeOnly" : false,
				"ifindex" : 9
			}
		],
		"dnssec" : "allow-downgrade",
		"dnsOverTLS" : "no",
		"llmnr" : "no",
		"mDNS" : "no",
		"scopes" : [
			{
				"protocol" : "dns",
				"ifindex" : 9,
				"ifname" : "eth0",
				"dnssec" : "allow-downgrade",
				"dnsOverTLS" : "no"
			}
		]
	}
]

Like the regular status output, fields are omitted all together when
empty, unless explicitly requested via one of the sub-commands dns,
domain, nta, etc.
2025-11-06 05:17:59 -05:00
Yu Watanabe c29e304562 Several OpenSSL related cleanups (#39455) 2025-11-02 17:21:51 +09:00
Yu Watanabe 4f589e8a50 resolvectl: fix typo
Follow-up for 7517e41a49.
2025-11-02 17:00:23 +09:00
Yu Watanabe a47a403ca2 resolvectl: return earlier from openpgp command when OpenSSL support is disabled
When OpenSSL is disabled, string_hashsum_sha256()/_sha224() in
resolve_openpgp() will fail anyway. Let's return earlier.
2025-11-02 16:07:46 +09:00
Lennart Poettering 7517e41a49 resolvectl: do not use strjoina() on user provided strings 2025-11-02 04:41:07 +09:00
Lennart Poettering 5751b236a5 resolved: move DNS RR/key/answer/question/packet tools to shared/
We want to reuse these generic DNS concepts in resolved hook
implementations, hence move them to shared code.

(This also enables us to immediately remove som SVCB record handling
duplicate definitions.)

No real code changes, just some moving around of things.
2025-10-20 10:35:23 +02:00