]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-conf.c
build-sys: use #if Y instead of #ifdef Y everywhere
[thirdparty/systemd.git] / src / resolve / resolved-conf.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2014 Tom Gundersen <teg@jklm.no>
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include "alloc-util.h"
21 #include "conf-parser.h"
22 #include "def.h"
23 #include "extract-word.h"
24 #include "parse-util.h"
25 #include "resolved-conf.h"
26 #include "string-table.h"
27 #include "string-util.h"
28
29 DEFINE_CONFIG_PARSE_ENUM(config_parse_dns_stub_listener_mode, dns_stub_listener_mode, DnsStubListenerMode, "Failed to parse DNS stub listener mode setting");
30
31 static const char* const dns_stub_listener_mode_table[_DNS_STUB_LISTENER_MODE_MAX] = {
32 [DNS_STUB_LISTENER_NO] = "no",
33 [DNS_STUB_LISTENER_UDP] = "udp",
34 [DNS_STUB_LISTENER_TCP] = "tcp",
35 [DNS_STUB_LISTENER_YES] = "yes",
36 };
37 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dns_stub_listener_mode, DnsStubListenerMode, DNS_STUB_LISTENER_YES);
38
39 int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char *word) {
40 union in_addr_union address;
41 int family, r, ifindex = 0;
42 DnsServer *s;
43
44 assert(m);
45 assert(word);
46
47 r = in_addr_ifindex_from_string_auto(word, &family, &address, &ifindex);
48 if (r < 0)
49 return r;
50
51 /* Silently filter out 0.0.0.0 and 127.0.0.53 (our own stub DNS listener) */
52 if (!dns_server_address_valid(family, &address))
53 return 0;
54
55 /* Filter out duplicates */
56 s = dns_server_find(manager_get_first_dns_server(m, type), family, &address, ifindex);
57 if (s) {
58 /*
59 * Drop the marker. This is used to find the servers
60 * that ceased to exist, see
61 * manager_mark_dns_servers() and
62 * manager_flush_marked_dns_servers().
63 */
64 dns_server_move_back_and_unmark(s);
65 return 0;
66 }
67
68 return dns_server_new(m, NULL, type, NULL, family, &address, ifindex);
69 }
70
71 int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
72 int r;
73
74 assert(m);
75 assert(string);
76
77 for (;;) {
78 _cleanup_free_ char *word = NULL;
79
80 r = extract_first_word(&string, &word, NULL, 0);
81 if (r < 0)
82 return r;
83 if (r == 0)
84 break;
85
86 r = manager_add_dns_server_by_string(m, type, word);
87 if (r < 0)
88 log_warning_errno(r, "Failed to add DNS server address '%s', ignoring: %m", word);
89 }
90
91 return 0;
92 }
93
94 int manager_add_search_domain_by_string(Manager *m, const char *domain) {
95 DnsSearchDomain *d;
96 bool route_only;
97 int r;
98
99 assert(m);
100 assert(domain);
101
102 route_only = *domain == '~';
103 if (route_only)
104 domain++;
105
106 if (dns_name_is_root(domain) || streq(domain, "*")) {
107 route_only = true;
108 domain = ".";
109 }
110
111 r = dns_search_domain_find(m->search_domains, domain, &d);
112 if (r < 0)
113 return r;
114 if (r > 0)
115 dns_search_domain_move_back_and_unmark(d);
116 else {
117 r = dns_search_domain_new(m, &d, DNS_SEARCH_DOMAIN_SYSTEM, NULL, domain);
118 if (r < 0)
119 return r;
120 }
121
122 d->route_only = route_only;
123 return 0;
124 }
125
126 int manager_parse_search_domains_and_warn(Manager *m, const char *string) {
127 int r;
128
129 assert(m);
130 assert(string);
131
132 for (;;) {
133 _cleanup_free_ char *word = NULL;
134
135 r = extract_first_word(&string, &word, NULL, EXTRACT_QUOTES);
136 if (r < 0)
137 return r;
138 if (r == 0)
139 break;
140
141 r = manager_add_search_domain_by_string(m, word);
142 if (r < 0)
143 log_warning_errno(r, "Failed to add search domain '%s', ignoring: %m", word);
144 }
145
146 return 0;
147 }
148
149 int config_parse_dns_servers(
150 const char *unit,
151 const char *filename,
152 unsigned line,
153 const char *section,
154 unsigned section_line,
155 const char *lvalue,
156 int ltype,
157 const char *rvalue,
158 void *data,
159 void *userdata) {
160
161 Manager *m = userdata;
162 int r;
163
164 assert(filename);
165 assert(lvalue);
166 assert(rvalue);
167 assert(m);
168
169 if (isempty(rvalue))
170 /* Empty assignment means clear the list */
171 dns_server_unlink_all(manager_get_first_dns_server(m, ltype));
172 else {
173 /* Otherwise, add to the list */
174 r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue);
175 if (r < 0) {
176 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
177 return 0;
178 }
179 }
180
181 /* If we have a manual setting, then we stop reading
182 * /etc/resolv.conf */
183 if (ltype == DNS_SERVER_SYSTEM)
184 m->read_resolv_conf = false;
185 if (ltype == DNS_SERVER_FALLBACK)
186 m->need_builtin_fallbacks = false;
187
188 return 0;
189 }
190
191 int config_parse_search_domains(
192 const char *unit,
193 const char *filename,
194 unsigned line,
195 const char *section,
196 unsigned section_line,
197 const char *lvalue,
198 int ltype,
199 const char *rvalue,
200 void *data,
201 void *userdata) {
202
203 Manager *m = userdata;
204 int r;
205
206 assert(filename);
207 assert(lvalue);
208 assert(rvalue);
209 assert(m);
210
211 if (isempty(rvalue))
212 /* Empty assignment means clear the list */
213 dns_search_domain_unlink_all(m->search_domains);
214 else {
215 /* Otherwise, add to the list */
216 r = manager_parse_search_domains_and_warn(m, rvalue);
217 if (r < 0) {
218 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse search domains string '%s'. Ignoring.", rvalue);
219 return 0;
220 }
221 }
222
223 /* If we have a manual setting, then we stop reading
224 * /etc/resolv.conf */
225 m->read_resolv_conf = false;
226
227 return 0;
228 }
229
230 int manager_parse_config_file(Manager *m) {
231 int r;
232
233 assert(m);
234
235 r = config_parse_many_nulstr(PKGSYSCONFDIR "/resolved.conf",
236 CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
237 "Resolve\0",
238 config_item_perf_lookup, resolved_gperf_lookup,
239 false, m);
240 if (r < 0)
241 return r;
242
243 if (m->need_builtin_fallbacks) {
244 r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
245 if (r < 0)
246 return r;
247 }
248
249 #if ! HAVE_GCRYPT
250 if (m->dnssec_mode != DNSSEC_NO) {
251 log_warning("DNSSEC option cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
252 m->dnssec_mode = DNSSEC_NO;
253 }
254 #endif
255 return 0;
256
257 }