]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/nspawn/nspawn-settings.c
tty-ask-password: Split out password sending
[thirdparty/systemd.git] / src / nspawn / nspawn-settings.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2015 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "alloc-util.h"
23 #include "cap-list.h"
24 #include "conf-parser.h"
25 #include "nspawn-network.h"
26 #include "nspawn-settings.h"
27 #include "process-util.h"
28 #include "strv.h"
29 #include "util.h"
30
31 int settings_load(FILE *f, const char *path, Settings **ret) {
32 _cleanup_(settings_freep) Settings *s = NULL;
33 int r;
34
35 assert(path);
36 assert(ret);
37
38 s = new0(Settings, 1);
39 if (!s)
40 return -ENOMEM;
41
42 s->boot = -1;
43 s->personality = PERSONALITY_INVALID;
44
45 s->read_only = -1;
46 s->volatile_mode = _VOLATILE_MODE_INVALID;
47
48 s->private_network = -1;
49 s->network_veth = -1;
50
51 r = config_parse(NULL, path, f,
52 "Exec\0"
53 "Network\0"
54 "Files\0",
55 config_item_perf_lookup, nspawn_gperf_lookup,
56 false,
57 false,
58 true,
59 s);
60 if (r < 0)
61 return r;
62
63 *ret = s;
64 s = NULL;
65
66 return 0;
67 }
68
69 Settings* settings_free(Settings *s) {
70
71 if (!s)
72 return NULL;
73
74 strv_free(s->parameters);
75 strv_free(s->environment);
76 free(s->user);
77
78 strv_free(s->network_interfaces);
79 strv_free(s->network_macvlan);
80 strv_free(s->network_ipvlan);
81 strv_free(s->network_veth_extra);
82 free(s->network_bridge);
83 expose_port_free_all(s->expose_ports);
84
85 custom_mount_free_all(s->custom_mounts, s->n_custom_mounts);
86 free(s);
87
88 return NULL;
89 }
90
91 bool settings_private_network(Settings *s) {
92 assert(s);
93
94 return
95 s->private_network > 0 ||
96 s->network_veth > 0 ||
97 s->network_bridge ||
98 s->network_interfaces ||
99 s->network_macvlan ||
100 s->network_ipvlan ||
101 s->network_veth_extra;
102 }
103
104 bool settings_network_veth(Settings *s) {
105 assert(s);
106
107 return
108 s->network_veth > 0 ||
109 s->network_bridge;
110 }
111
112 DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
113
114 int config_parse_expose_port(
115 const char *unit,
116 const char *filename,
117 unsigned line,
118 const char *section,
119 unsigned section_line,
120 const char *lvalue,
121 int ltype,
122 const char *rvalue,
123 void *data,
124 void *userdata) {
125
126 Settings *s = data;
127 int r;
128
129 assert(filename);
130 assert(lvalue);
131 assert(rvalue);
132
133 r = expose_port_parse(&s->expose_ports, rvalue);
134 if (r == -EEXIST) {
135 log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate port specification, ignoring: %s", rvalue);
136 return 0;
137 }
138 if (r < 0) {
139 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse host port %s: %m", rvalue);
140 return 0;
141 }
142
143 return 0;
144 }
145
146 int config_parse_capability(
147 const char *unit,
148 const char *filename,
149 unsigned line,
150 const char *section,
151 unsigned section_line,
152 const char *lvalue,
153 int ltype,
154 const char *rvalue,
155 void *data,
156 void *userdata) {
157
158 uint64_t u = 0, *result = data;
159 int r;
160
161 assert(filename);
162 assert(lvalue);
163 assert(rvalue);
164
165 for (;;) {
166 _cleanup_free_ char *word = NULL;
167 int cap;
168
169 r = extract_first_word(&rvalue, &word, NULL, 0);
170 if (r < 0) {
171 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract capability string, ignoring: %s", rvalue);
172 return 0;
173 }
174 if (r == 0)
175 break;
176
177 cap = capability_from_name(word);
178 if (cap < 0) {
179 log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability, ignoring: %s", word);
180 continue;
181 }
182
183 u |= 1 << ((uint64_t) cap);
184 }
185
186 if (u == 0)
187 return 0;
188
189 *result |= u;
190 return 0;
191 }
192
193 int config_parse_id128(
194 const char *unit,
195 const char *filename,
196 unsigned line,
197 const char *section,
198 unsigned section_line,
199 const char *lvalue,
200 int ltype,
201 const char *rvalue,
202 void *data,
203 void *userdata) {
204
205 sd_id128_t t, *result = data;
206 int r;
207
208 assert(filename);
209 assert(lvalue);
210 assert(rvalue);
211
212 r = sd_id128_from_string(rvalue, &t);
213 if (r < 0) {
214 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse 128bit ID/UUID, ignoring: %s", rvalue);
215 return 0;
216 }
217
218 *result = t;
219 return 0;
220 }
221
222 int config_parse_bind(
223 const char *unit,
224 const char *filename,
225 unsigned line,
226 const char *section,
227 unsigned section_line,
228 const char *lvalue,
229 int ltype,
230 const char *rvalue,
231 void *data,
232 void *userdata) {
233
234 Settings *settings = data;
235 int r;
236
237 assert(filename);
238 assert(lvalue);
239 assert(rvalue);
240
241 r = bind_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
242 if (r < 0) {
243 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid bind mount specification %s: %m", rvalue);
244 return 0;
245 }
246
247 return 0;
248 }
249
250 int config_parse_tmpfs(
251 const char *unit,
252 const char *filename,
253 unsigned line,
254 const char *section,
255 unsigned section_line,
256 const char *lvalue,
257 int ltype,
258 const char *rvalue,
259 void *data,
260 void *userdata) {
261
262 Settings *settings = data;
263 int r;
264
265 assert(filename);
266 assert(lvalue);
267 assert(rvalue);
268
269 r = tmpfs_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
270 if (r < 0) {
271 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid temporary file system specification %s: %m", rvalue);
272 return 0;
273 }
274
275 return 0;
276 }
277
278 int config_parse_veth_extra(
279 const char *unit,
280 const char *filename,
281 unsigned line,
282 const char *section,
283 unsigned section_line,
284 const char *lvalue,
285 int ltype,
286 const char *rvalue,
287 void *data,
288 void *userdata) {
289
290 Settings *settings = data;
291 int r;
292
293 assert(filename);
294 assert(lvalue);
295 assert(rvalue);
296
297 r = veth_extra_parse(&settings->network_veth_extra, rvalue);
298 if (r < 0) {
299 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid extra virtual Ethernet link specification %s: %m", rvalue);
300 return 0;
301 }
302
303 return 0;
304 }