]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-util.c
Merge pull request #30284 from YHNdnzj/fstab-wantedby-defaultdeps
[thirdparty/systemd.git] / src / resolve / resolved-util.c
CommitLineData
75c9d6b5
ZJS
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3#include "dns-def.h"
4#include "dns-domain.h"
5#include "hostname-util.h"
6#include "idn-util.h"
7#include "resolved-util.h"
8#include "utf8.h"
9
10int resolve_system_hostname(char **full_hostname, char **first_label) {
11 _cleanup_free_ char *h = NULL, *n = NULL;
12#if HAVE_LIBIDN2
13 _cleanup_free_ char *utf8 = NULL;
14#elif HAVE_LIBIDN
15 int k;
16#endif
f5de77fa 17 char label[DNS_LABEL_MAX+1];
75c9d6b5
ZJS
18 const char *p, *decoded;
19 int r;
20
21 /* Return the full hostname in *full_hostname, if nonnull.
22 *
23 * Extract and normalize the first label of the locally configured hostname, check it's not
24 * "localhost", and return it in *first_label, if nonnull. */
25
26 r = gethostname_strict(&h);
27 if (r < 0)
28 return log_debug_errno(r, "Can't determine system hostname: %m");
29
30 p = h;
31 r = dns_label_unescape(&p, label, sizeof label, 0);
32 if (r < 0)
33 return log_debug_errno(r, "Failed to unescape hostname: %m");
34 if (r == 0)
35 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
36 "Couldn't find a single label in hostname.");
37
38#if HAVE_LIBIDN || HAVE_LIBIDN2
39 r = dlopen_idn();
40 if (r < 0) {
41 log_debug_errno(r, "Failed to initialize IDN support, ignoring: %m");
42 decoded = label; /* no decoding */
43 } else
44#endif
45 {
46#if HAVE_LIBIDN2
47 r = sym_idn2_to_unicode_8z8z(label, &utf8, 0);
48 if (r != IDN2_OK)
49 return log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
50 "Failed to undo IDNA: %s", sym_idn2_strerror(r));
51 assert(utf8_is_valid(utf8));
52
53 r = strlen(utf8);
54 decoded = utf8;
55#elif HAVE_LIBIDN
56 k = dns_label_undo_idna(label, r, label, sizeof label);
57 if (k < 0)
58 return log_debug_errno(k, "Failed to undo IDNA: %m");
59 if (k > 0)
60 r = k;
61
62 if (!utf8_is_valid(label))
63 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
64 "System hostname is not UTF-8 clean.");
65 decoded = label;
66#else
67 decoded = label; /* no decoding */
68#endif
69 }
70
71 r = dns_label_escape_new(decoded, r, &n);
72 if (r < 0)
73 return log_debug_errno(r, "Failed to escape hostname: %m");
74
75 if (is_localhost(n))
76 return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
77 "System hostname is 'localhost', ignoring.");
78
79 if (full_hostname)
80 *full_hostname = TAKE_PTR(h);
81 if (first_label)
82 *first_label = TAKE_PTR(n);
83 return 0;
84}