]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-conf.c
resolved: respond to local resolver requests on 127.0.0.53:53
[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-util.h"
27
28 int manager_add_dns_server_by_string(Manager *m, DnsServerType type, const char *word) {
29 union in_addr_union address;
30 int family, r, ifindex = 0;
31 DnsServer *s;
32
33 assert(m);
34 assert(word);
35
36 r = in_addr_ifindex_from_string_auto(word, &family, &address, &ifindex);
37 if (r < 0)
38 return r;
39
40 /* Silently filter out 0.0.0.0 and 127.0.0.53 (our own stub DNS listener) */
41 if (!dns_server_address_valid(family, &address))
42 return 0;
43
44 /* Filter out duplicates */
45 s = dns_server_find(manager_get_first_dns_server(m, type), family, &address, ifindex);
46 if (s) {
47 /*
48 * Drop the marker. This is used to find the servers
49 * that ceased to exist, see
50 * manager_mark_dns_servers() and
51 * manager_flush_marked_dns_servers().
52 */
53 dns_server_move_back_and_unmark(s);
54 return 0;
55 }
56
57 return dns_server_new(m, NULL, type, NULL, family, &address, ifindex);
58 }
59
60 int manager_parse_dns_server_string_and_warn(Manager *m, DnsServerType type, const char *string) {
61 int r;
62
63 assert(m);
64 assert(string);
65
66 for (;;) {
67 _cleanup_free_ char *word = NULL;
68
69 r = extract_first_word(&string, &word, NULL, 0);
70 if (r < 0)
71 return r;
72 if (r == 0)
73 break;
74
75 r = manager_add_dns_server_by_string(m, type, word);
76 if (r < 0)
77 log_warning_errno(r, "Failed to add DNS server address '%s', ignoring: %m", word);
78 }
79
80 return 0;
81 }
82
83 int manager_add_search_domain_by_string(Manager *m, const char *domain) {
84 DnsSearchDomain *d;
85 bool route_only;
86 int r;
87
88 assert(m);
89 assert(domain);
90
91 route_only = *domain == '~';
92 if (route_only)
93 domain++;
94
95 if (dns_name_is_root(domain) || streq(domain, "*")) {
96 route_only = true;
97 domain = ".";
98 }
99
100 r = dns_search_domain_find(m->search_domains, domain, &d);
101 if (r < 0)
102 return r;
103 if (r > 0)
104 dns_search_domain_move_back_and_unmark(d);
105 else {
106 r = dns_search_domain_new(m, &d, DNS_SEARCH_DOMAIN_SYSTEM, NULL, domain);
107 if (r < 0)
108 return r;
109 }
110
111 d->route_only = route_only;
112 return 0;
113 }
114
115 int manager_parse_search_domains_and_warn(Manager *m, const char *string) {
116 int r;
117
118 assert(m);
119 assert(string);
120
121 for (;;) {
122 _cleanup_free_ char *word = NULL;
123
124 r = extract_first_word(&string, &word, NULL, EXTRACT_QUOTES);
125 if (r < 0)
126 return r;
127 if (r == 0)
128 break;
129
130 r = manager_add_search_domain_by_string(m, word);
131 if (r < 0)
132 log_warning_errno(r, "Failed to add search domain '%s', ignoring: %m", word);
133 }
134
135 return 0;
136 }
137
138 int config_parse_dns_servers(
139 const char *unit,
140 const char *filename,
141 unsigned line,
142 const char *section,
143 unsigned section_line,
144 const char *lvalue,
145 int ltype,
146 const char *rvalue,
147 void *data,
148 void *userdata) {
149
150 Manager *m = userdata;
151 int r;
152
153 assert(filename);
154 assert(lvalue);
155 assert(rvalue);
156 assert(m);
157
158 if (isempty(rvalue))
159 /* Empty assignment means clear the list */
160 dns_server_unlink_all(manager_get_first_dns_server(m, ltype));
161 else {
162 /* Otherwise, add to the list */
163 r = manager_parse_dns_server_string_and_warn(m, ltype, rvalue);
164 if (r < 0) {
165 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNS server string '%s'. Ignoring.", rvalue);
166 return 0;
167 }
168 }
169
170 /* If we have a manual setting, then we stop reading
171 * /etc/resolv.conf */
172 if (ltype == DNS_SERVER_SYSTEM)
173 m->read_resolv_conf = false;
174 if (ltype == DNS_SERVER_FALLBACK)
175 m->need_builtin_fallbacks = false;
176
177 return 0;
178 }
179
180 int config_parse_search_domains(
181 const char *unit,
182 const char *filename,
183 unsigned line,
184 const char *section,
185 unsigned section_line,
186 const char *lvalue,
187 int ltype,
188 const char *rvalue,
189 void *data,
190 void *userdata) {
191
192 Manager *m = userdata;
193 int r;
194
195 assert(filename);
196 assert(lvalue);
197 assert(rvalue);
198 assert(m);
199
200 if (isempty(rvalue))
201 /* Empty assignment means clear the list */
202 dns_search_domain_unlink_all(m->search_domains);
203 else {
204 /* Otherwise, add to the list */
205 r = manager_parse_search_domains_and_warn(m, rvalue);
206 if (r < 0) {
207 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse search domains string '%s'. Ignoring.", rvalue);
208 return 0;
209 }
210 }
211
212 /* If we have a manual setting, then we stop reading
213 * /etc/resolv.conf */
214 m->read_resolv_conf = false;
215
216 return 0;
217 }
218
219 int manager_parse_config_file(Manager *m) {
220 int r;
221
222 assert(m);
223
224 r = config_parse_many(PKGSYSCONFDIR "/resolved.conf",
225 CONF_PATHS_NULSTR("systemd/resolved.conf.d"),
226 "Resolve\0",
227 config_item_perf_lookup, resolved_gperf_lookup,
228 false, m);
229 if (r < 0)
230 return r;
231
232 if (m->need_builtin_fallbacks) {
233 r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
234 if (r < 0)
235 return r;
236 }
237
238 return 0;
239
240 }