LCOV - code coverage report
Current view: top level - nspawn - nspawn-settings.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 6 387 1.6 %
Date: 2019-08-22 15:41:25 Functions: 5 34 14.7 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: LGPL-2.1+ */
       2             : 
       3             : #include "alloc-util.h"
       4             : #include "cap-list.h"
       5             : #include "conf-parser.h"
       6             : #include "cpu-set-util.h"
       7             : #include "hostname-util.h"
       8             : #include "nspawn-network.h"
       9             : #include "nspawn-settings.h"
      10             : #include "parse-util.h"
      11             : #include "process-util.h"
      12             : #include "rlimit-util.h"
      13             : #include "socket-util.h"
      14             : #include "string-table.h"
      15             : #include "string-util.h"
      16             : #include "strv.h"
      17             : #include "user-util.h"
      18             : #include "util.h"
      19             : 
      20           0 : Settings *settings_new(void) {
      21             :         Settings *s;
      22             : 
      23           0 :         s = new(Settings, 1);
      24           0 :         if (!s)
      25           0 :                 return NULL;
      26             : 
      27           0 :         *s = (Settings) {
      28             :                 .start_mode = _START_MODE_INVALID,
      29             :                 .personality = PERSONALITY_INVALID,
      30             : 
      31             :                 .resolv_conf = _RESOLV_CONF_MODE_INVALID,
      32             :                 .link_journal = _LINK_JOURNAL_INVALID,
      33             :                 .timezone = _TIMEZONE_MODE_INVALID,
      34             : 
      35             :                 .userns_mode = _USER_NAMESPACE_MODE_INVALID,
      36             :                 .userns_chown = -1,
      37             :                 .uid_shift = UID_INVALID,
      38             :                 .uid_range = UID_INVALID,
      39             : 
      40             :                 .no_new_privileges = -1,
      41             : 
      42             :                 .read_only = -1,
      43             :                 .volatile_mode = _VOLATILE_MODE_INVALID,
      44             : 
      45             :                 .private_network = -1,
      46             :                 .network_veth = -1,
      47             : 
      48             :                 .full_capabilities = CAPABILITY_QUINTET_NULL,
      49             : 
      50             :                 .uid = UID_INVALID,
      51             :                 .gid = GID_INVALID,
      52             : 
      53             :                 .console_mode = _CONSOLE_MODE_INVALID,
      54             :                 .console_width = (unsigned) -1,
      55             :                 .console_height = (unsigned) -1,
      56             : 
      57             :                 .clone_ns_flags = (unsigned long) -1,
      58             :                 .use_cgns = -1,
      59             :         };
      60             : 
      61           0 :         return s;
      62             : }
      63             : 
      64           0 : int settings_load(FILE *f, const char *path, Settings **ret) {
      65           0 :         _cleanup_(settings_freep) Settings *s = NULL;
      66             :         int r;
      67             : 
      68           0 :         assert(path);
      69           0 :         assert(ret);
      70             : 
      71           0 :         s = settings_new();
      72           0 :         if (!s)
      73           0 :                 return -ENOMEM;
      74             : 
      75           0 :         r = config_parse(NULL, path, f,
      76             :                          "Exec\0"
      77             :                          "Network\0"
      78             :                          "Files\0",
      79             :                          config_item_perf_lookup, nspawn_gperf_lookup,
      80             :                          CONFIG_PARSE_WARN,
      81             :                          s);
      82           0 :         if (r < 0)
      83           0 :                 return r;
      84             : 
      85             :         /* Make sure that if userns_mode is set, userns_chown is set to something appropriate, and vice versa. Either
      86             :          * both fields shall be initialized or neither. */
      87           0 :         if (s->userns_mode == USER_NAMESPACE_PICK)
      88           0 :                 s->userns_chown = true;
      89           0 :         else if (s->userns_mode != _USER_NAMESPACE_MODE_INVALID && s->userns_chown < 0)
      90           0 :                 s->userns_chown = false;
      91             : 
      92           0 :         if (s->userns_chown >= 0 && s->userns_mode == _USER_NAMESPACE_MODE_INVALID)
      93           0 :                 s->userns_mode = USER_NAMESPACE_NO;
      94             : 
      95           0 :         *ret = TAKE_PTR(s);
      96           0 :         return 0;
      97             : }
      98             : 
      99           0 : static void free_oci_hooks(OciHook *h, size_t n) {
     100             :         size_t i;
     101             : 
     102           0 :         assert(h || n == 0);
     103             : 
     104           0 :         for (i = 0; i < n; i++) {
     105           0 :                 free(h[i].path);
     106           0 :                 strv_free(h[i].args);
     107           0 :                 strv_free(h[i].env);
     108             :         }
     109             : 
     110           0 :         free(h);
     111           0 : }
     112             : 
     113           4 : void device_node_array_free(DeviceNode *node, size_t n) {
     114             :         size_t i;
     115             : 
     116           4 :         for (i = 0; i < n; i++)
     117           0 :                 free(node[i].path);
     118             : 
     119           4 :         free(node);
     120           4 : }
     121             : 
     122           0 : Settings* settings_free(Settings *s) {
     123           0 :         if (!s)
     124           0 :                 return NULL;
     125             : 
     126           0 :         strv_free(s->parameters);
     127           0 :         strv_free(s->environment);
     128           0 :         free(s->user);
     129           0 :         free(s->pivot_root_new);
     130           0 :         free(s->pivot_root_old);
     131           0 :         free(s->working_directory);
     132           0 :         strv_free(s->syscall_whitelist);
     133           0 :         strv_free(s->syscall_blacklist);
     134           0 :         rlimit_free_all(s->rlimit);
     135           0 :         free(s->hostname);
     136           0 :         cpu_set_reset(&s->cpu_set);
     137             : 
     138           0 :         strv_free(s->network_interfaces);
     139           0 :         strv_free(s->network_macvlan);
     140           0 :         strv_free(s->network_ipvlan);
     141           0 :         strv_free(s->network_veth_extra);
     142           0 :         free(s->network_bridge);
     143           0 :         free(s->network_zone);
     144           0 :         expose_port_free_all(s->expose_ports);
     145             : 
     146           0 :         custom_mount_free_all(s->custom_mounts, s->n_custom_mounts);
     147             : 
     148           0 :         free(s->bundle);
     149           0 :         free(s->root);
     150             : 
     151           0 :         free_oci_hooks(s->oci_hooks_prestart, s->n_oci_hooks_prestart);
     152           0 :         free_oci_hooks(s->oci_hooks_poststart, s->n_oci_hooks_poststart);
     153           0 :         free_oci_hooks(s->oci_hooks_poststop, s->n_oci_hooks_poststop);
     154             : 
     155           0 :         free(s->slice);
     156           0 :         sd_bus_message_unref(s->properties);
     157             : 
     158           0 :         free(s->supplementary_gids);
     159           0 :         device_node_array_free(s->extra_nodes, s->n_extra_nodes);
     160           0 :         free(s->network_namespace_path);
     161             : 
     162           0 :         strv_free(s->sysctl);
     163             : 
     164             : #if HAVE_SECCOMP
     165           0 :         seccomp_release(s->seccomp);
     166             : #endif
     167             : 
     168           0 :         return mfree(s);
     169             : }
     170             : 
     171           0 : bool settings_private_network(Settings *s) {
     172           0 :         assert(s);
     173             : 
     174             :         return
     175           0 :                 s->private_network > 0 ||
     176           0 :                 s->network_veth > 0 ||
     177           0 :                 s->network_bridge ||
     178           0 :                 s->network_zone ||
     179           0 :                 s->network_interfaces ||
     180           0 :                 s->network_macvlan ||
     181           0 :                 s->network_ipvlan ||
     182           0 :                 s->network_veth_extra;
     183             : }
     184             : 
     185           0 : bool settings_network_veth(Settings *s) {
     186           0 :         assert(s);
     187             : 
     188             :         return
     189           0 :                 s->network_veth > 0 ||
     190           0 :                 s->network_bridge ||
     191           0 :                 s->network_zone;
     192             : }
     193             : 
     194           0 : int settings_allocate_properties(Settings *s) {
     195           0 :         _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
     196             :         int r;
     197             : 
     198           0 :         assert(s);
     199             : 
     200           0 :         if (s->properties)
     201           0 :                 return 0;
     202             : 
     203           0 :         r = sd_bus_default_system(&bus);
     204           0 :         if (r < 0)
     205           0 :                 return r;
     206             : 
     207           0 :         r = sd_bus_message_new(bus, &s->properties, SD_BUS_MESSAGE_METHOD_CALL);
     208           0 :         if (r < 0)
     209           0 :                 return r;
     210             : 
     211           0 :         return 0;
     212             : }
     213             : 
     214           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
     215             : 
     216           0 : int config_parse_expose_port(
     217             :                 const char *unit,
     218             :                 const char *filename,
     219             :                 unsigned line,
     220             :                 const char *section,
     221             :                 unsigned section_line,
     222             :                 const char *lvalue,
     223             :                 int ltype,
     224             :                 const char *rvalue,
     225             :                 void *data,
     226             :                 void *userdata) {
     227             : 
     228           0 :         Settings *s = data;
     229             :         int r;
     230             : 
     231           0 :         assert(filename);
     232           0 :         assert(lvalue);
     233           0 :         assert(rvalue);
     234             : 
     235           0 :         r = expose_port_parse(&s->expose_ports, rvalue);
     236           0 :         if (r == -EEXIST) {
     237           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Duplicate port specification, ignoring: %s", rvalue);
     238           0 :                 return 0;
     239             :         }
     240           0 :         if (r < 0) {
     241           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse host port %s: %m", rvalue);
     242           0 :                 return 0;
     243             :         }
     244             : 
     245           0 :         return 0;
     246             : }
     247             : 
     248           0 : int config_parse_capability(
     249             :                 const char *unit,
     250             :                 const char *filename,
     251             :                 unsigned line,
     252             :                 const char *section,
     253             :                 unsigned section_line,
     254             :                 const char *lvalue,
     255             :                 int ltype,
     256             :                 const char *rvalue,
     257             :                 void *data,
     258             :                 void *userdata) {
     259             : 
     260           0 :         uint64_t u = 0, *result = data;
     261             :         int r;
     262             : 
     263           0 :         assert(filename);
     264           0 :         assert(lvalue);
     265           0 :         assert(rvalue);
     266             : 
     267           0 :         for (;;) {
     268           0 :                 _cleanup_free_ char *word = NULL;
     269             : 
     270           0 :                 r = extract_first_word(&rvalue, &word, NULL, 0);
     271           0 :                 if (r < 0) {
     272           0 :                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract capability string, ignoring: %s", rvalue);
     273           0 :                         return 0;
     274             :                 }
     275           0 :                 if (r == 0)
     276           0 :                         break;
     277             : 
     278           0 :                 r = capability_from_name(word);
     279           0 :                 if (r < 0) {
     280           0 :                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse capability, ignoring: %s", word);
     281           0 :                         continue;
     282             :                 }
     283             : 
     284           0 :                 u |= UINT64_C(1) << r;
     285             :         }
     286             : 
     287           0 :         if (u == 0)
     288           0 :                 return 0;
     289             : 
     290           0 :         *result |= u;
     291           0 :         return 0;
     292             : }
     293             : 
     294           0 : int config_parse_id128(
     295             :                 const char *unit,
     296             :                 const char *filename,
     297             :                 unsigned line,
     298             :                 const char *section,
     299             :                 unsigned section_line,
     300             :                 const char *lvalue,
     301             :                 int ltype,
     302             :                 const char *rvalue,
     303             :                 void *data,
     304             :                 void *userdata) {
     305             : 
     306           0 :         sd_id128_t t, *result = data;
     307             :         int r;
     308             : 
     309           0 :         assert(filename);
     310           0 :         assert(lvalue);
     311           0 :         assert(rvalue);
     312             : 
     313           0 :         r = sd_id128_from_string(rvalue, &t);
     314           0 :         if (r < 0) {
     315           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse 128bit ID/UUID, ignoring: %s", rvalue);
     316           0 :                 return 0;
     317             :         }
     318             : 
     319           0 :         *result = t;
     320           0 :         return 0;
     321             : }
     322             : 
     323           0 : int config_parse_pivot_root(
     324             :                 const char *unit,
     325             :                 const char *filename,
     326             :                 unsigned line,
     327             :                 const char *section,
     328             :                 unsigned section_line,
     329             :                 const char *lvalue,
     330             :                 int ltype,
     331             :                 const char *rvalue,
     332             :                 void *data,
     333             :                 void *userdata) {
     334             : 
     335           0 :         Settings *settings = data;
     336             :         int r;
     337             : 
     338           0 :         assert(filename);
     339           0 :         assert(lvalue);
     340           0 :         assert(rvalue);
     341             : 
     342           0 :         r = pivot_root_parse(&settings->pivot_root_new, &settings->pivot_root_old, rvalue);
     343           0 :         if (r < 0) {
     344           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid pivot root mount specification %s: %m", rvalue);
     345           0 :                 return 0;
     346             :         }
     347             : 
     348           0 :         return 0;
     349             : }
     350             : 
     351           0 : int config_parse_bind(
     352             :                 const char *unit,
     353             :                 const char *filename,
     354             :                 unsigned line,
     355             :                 const char *section,
     356             :                 unsigned section_line,
     357             :                 const char *lvalue,
     358             :                 int ltype,
     359             :                 const char *rvalue,
     360             :                 void *data,
     361             :                 void *userdata) {
     362             : 
     363           0 :         Settings *settings = data;
     364             :         int r;
     365             : 
     366           0 :         assert(filename);
     367           0 :         assert(lvalue);
     368           0 :         assert(rvalue);
     369             : 
     370           0 :         r = bind_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
     371           0 :         if (r < 0) {
     372           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid bind mount specification %s: %m", rvalue);
     373           0 :                 return 0;
     374             :         }
     375             : 
     376           0 :         return 0;
     377             : }
     378             : 
     379           0 : int config_parse_tmpfs(
     380             :                 const char *unit,
     381             :                 const char *filename,
     382             :                 unsigned line,
     383             :                 const char *section,
     384             :                 unsigned section_line,
     385             :                 const char *lvalue,
     386             :                 int ltype,
     387             :                 const char *rvalue,
     388             :                 void *data,
     389             :                 void *userdata) {
     390             : 
     391           0 :         Settings *settings = data;
     392             :         int r;
     393             : 
     394           0 :         assert(filename);
     395           0 :         assert(lvalue);
     396           0 :         assert(rvalue);
     397             : 
     398           0 :         r = tmpfs_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
     399           0 :         if (r < 0) {
     400           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid temporary file system specification %s: %m", rvalue);
     401           0 :                 return 0;
     402             :         }
     403             : 
     404           0 :         return 0;
     405             : }
     406             : 
     407           0 : int config_parse_inaccessible(
     408             :                 const char *unit,
     409             :                 const char *filename,
     410             :                 unsigned line,
     411             :                 const char *section,
     412             :                 unsigned section_line,
     413             :                 const char *lvalue,
     414             :                 int ltype,
     415             :                 const char *rvalue,
     416             :                 void *data,
     417             :                 void *userdata) {
     418             : 
     419           0 :         Settings *settings = data;
     420             :         int r;
     421             : 
     422           0 :         assert(filename);
     423           0 :         assert(lvalue);
     424           0 :         assert(rvalue);
     425             : 
     426           0 :         r = inaccessible_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue);
     427           0 :         if (r < 0) {
     428           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid inaccessible file system specification %s: %m", rvalue);
     429           0 :                 return 0;
     430             :         }
     431             : 
     432           0 :         return 0;
     433             : }
     434             : 
     435           0 : int config_parse_overlay(
     436             :                 const char *unit,
     437             :                 const char *filename,
     438             :                 unsigned line,
     439             :                 const char *section,
     440             :                 unsigned section_line,
     441             :                 const char *lvalue,
     442             :                 int ltype,
     443             :                 const char *rvalue,
     444             :                 void *data,
     445             :                 void *userdata) {
     446             : 
     447           0 :         Settings *settings = data;
     448             :         int r;
     449             : 
     450           0 :         assert(filename);
     451           0 :         assert(lvalue);
     452           0 :         assert(rvalue);
     453             : 
     454           0 :         r = overlay_mount_parse(&settings->custom_mounts, &settings->n_custom_mounts, rvalue, ltype);
     455           0 :         if (r < 0)
     456           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid overlay file system specification %s, ignoring: %m", rvalue);
     457             : 
     458           0 :         return 0;
     459             : }
     460             : 
     461           0 : int config_parse_veth_extra(
     462             :                 const char *unit,
     463             :                 const char *filename,
     464             :                 unsigned line,
     465             :                 const char *section,
     466             :                 unsigned section_line,
     467             :                 const char *lvalue,
     468             :                 int ltype,
     469             :                 const char *rvalue,
     470             :                 void *data,
     471             :                 void *userdata) {
     472             : 
     473           0 :         Settings *settings = data;
     474             :         int r;
     475             : 
     476           0 :         assert(filename);
     477           0 :         assert(lvalue);
     478           0 :         assert(rvalue);
     479             : 
     480           0 :         r = veth_extra_parse(&settings->network_veth_extra, rvalue);
     481           0 :         if (r < 0) {
     482           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Invalid extra virtual Ethernet link specification %s: %m", rvalue);
     483           0 :                 return 0;
     484             :         }
     485             : 
     486           0 :         return 0;
     487             : }
     488             : 
     489           0 : int config_parse_network_zone(
     490             :                 const char *unit,
     491             :                 const char *filename,
     492             :                 unsigned line,
     493             :                 const char *section,
     494             :                 unsigned section_line,
     495             :                 const char *lvalue,
     496             :                 int ltype,
     497             :                 const char *rvalue,
     498             :                 void *data,
     499             :                 void *userdata) {
     500             : 
     501           0 :         Settings *settings = data;
     502           0 :         _cleanup_free_ char *j = NULL;
     503             : 
     504           0 :         assert(filename);
     505           0 :         assert(lvalue);
     506           0 :         assert(rvalue);
     507             : 
     508           0 :         j = strjoin("vz-", rvalue);
     509           0 :         if (!ifname_valid(j)) {
     510           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid network zone name, ignoring: %s", rvalue);
     511           0 :                 return 0;
     512             :         }
     513             : 
     514           0 :         free_and_replace(settings->network_zone, j);
     515             : 
     516           0 :         return 0;
     517             : }
     518             : 
     519           0 : int config_parse_boot(
     520             :                 const char *unit,
     521             :                 const char *filename,
     522             :                 unsigned line,
     523             :                 const char *section,
     524             :                 unsigned section_line,
     525             :                 const char *lvalue,
     526             :                 int ltype,
     527             :                 const char *rvalue,
     528             :                 void *data,
     529             :                 void *userdata) {
     530             : 
     531           0 :         Settings *settings = data;
     532             :         int r;
     533             : 
     534           0 :         assert(filename);
     535           0 :         assert(lvalue);
     536           0 :         assert(rvalue);
     537             : 
     538           0 :         r = parse_boolean(rvalue);
     539           0 :         if (r < 0) {
     540           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse Boot= parameter %s, ignoring: %m", rvalue);
     541           0 :                 return 0;
     542             :         }
     543             : 
     544           0 :         if (r > 0) {
     545           0 :                 if (settings->start_mode == START_PID2)
     546           0 :                         goto conflict;
     547             : 
     548           0 :                 settings->start_mode = START_BOOT;
     549             :         } else {
     550           0 :                 if (settings->start_mode == START_BOOT)
     551           0 :                         goto conflict;
     552             : 
     553           0 :                 if (settings->start_mode < 0)
     554           0 :                         settings->start_mode = START_PID1;
     555             :         }
     556             : 
     557           0 :         return 0;
     558             : 
     559           0 : conflict:
     560           0 :         log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
     561           0 :         return 0;
     562             : }
     563             : 
     564           0 : int config_parse_pid2(
     565             :                 const char *unit,
     566             :                 const char *filename,
     567             :                 unsigned line,
     568             :                 const char *section,
     569             :                 unsigned section_line,
     570             :                 const char *lvalue,
     571             :                 int ltype,
     572             :                 const char *rvalue,
     573             :                 void *data,
     574             :                 void *userdata) {
     575             : 
     576           0 :         Settings *settings = data;
     577             :         int r;
     578             : 
     579           0 :         assert(filename);
     580           0 :         assert(lvalue);
     581           0 :         assert(rvalue);
     582             : 
     583           0 :         r = parse_boolean(rvalue);
     584           0 :         if (r < 0) {
     585           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse ProcessTwo= parameter %s, ignoring: %m", rvalue);
     586           0 :                 return 0;
     587             :         }
     588             : 
     589           0 :         if (r > 0) {
     590           0 :                 if (settings->start_mode == START_BOOT)
     591           0 :                         goto conflict;
     592             : 
     593           0 :                 settings->start_mode = START_PID2;
     594             :         } else {
     595           0 :                 if (settings->start_mode == START_PID2)
     596           0 :                         goto conflict;
     597             : 
     598           0 :                 if (settings->start_mode < 0)
     599           0 :                         settings->start_mode = START_PID1;
     600             :         }
     601             : 
     602           0 :         return 0;
     603             : 
     604           0 : conflict:
     605           0 :         log_syntax(unit, LOG_ERR, filename, line, r, "Conflicting Boot= or ProcessTwo= setting found. Ignoring.");
     606           0 :         return 0;
     607             : }
     608             : 
     609           0 : int config_parse_private_users(
     610             :                 const char *unit,
     611             :                 const char *filename,
     612             :                 unsigned line,
     613             :                 const char *section,
     614             :                 unsigned section_line,
     615             :                 const char *lvalue,
     616             :                 int ltype,
     617             :                 const char *rvalue,
     618             :                 void *data,
     619             :                 void *userdata) {
     620             : 
     621           0 :         Settings *settings = data;
     622             :         int r;
     623             : 
     624           0 :         assert(filename);
     625           0 :         assert(lvalue);
     626           0 :         assert(rvalue);
     627             : 
     628           0 :         r = parse_boolean(rvalue);
     629           0 :         if (r == 0) {
     630             :                 /* no: User namespacing off */
     631           0 :                 settings->userns_mode = USER_NAMESPACE_NO;
     632           0 :                 settings->uid_shift = UID_INVALID;
     633           0 :                 settings->uid_range = UINT32_C(0x10000);
     634           0 :         } else if (r > 0) {
     635             :                 /* yes: User namespacing on, UID range is read from root dir */
     636           0 :                 settings->userns_mode = USER_NAMESPACE_FIXED;
     637           0 :                 settings->uid_shift = UID_INVALID;
     638           0 :                 settings->uid_range = UINT32_C(0x10000);
     639           0 :         } else if (streq(rvalue, "pick")) {
     640             :                 /* pick: User namespacing on, UID range is picked randomly */
     641           0 :                 settings->userns_mode = USER_NAMESPACE_PICK;
     642           0 :                 settings->uid_shift = UID_INVALID;
     643           0 :                 settings->uid_range = UINT32_C(0x10000);
     644             :         } else {
     645             :                 const char *range, *shift;
     646             :                 uid_t sh, rn;
     647             : 
     648             :                 /* anything else: User namespacing on, UID range is explicitly configured */
     649             : 
     650           0 :                 range = strchr(rvalue, ':');
     651           0 :                 if (range) {
     652           0 :                         shift = strndupa(rvalue, range - rvalue);
     653           0 :                         range++;
     654             : 
     655           0 :                         r = safe_atou32(range, &rn);
     656           0 :                         if (r < 0 || rn <= 0) {
     657           0 :                                 log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID range invalid, ignoring: %s", range);
     658           0 :                                 return 0;
     659             :                         }
     660             :                 } else {
     661           0 :                         shift = rvalue;
     662           0 :                         rn = UINT32_C(0x10000);
     663             :                 }
     664             : 
     665           0 :                 r = parse_uid(shift, &sh);
     666           0 :                 if (r < 0) {
     667           0 :                         log_syntax(unit, LOG_ERR, filename, line, r, "UID/GID shift invalid, ignoring: %s", range);
     668           0 :                         return 0;
     669             :                 }
     670             : 
     671           0 :                 settings->userns_mode = USER_NAMESPACE_FIXED;
     672           0 :                 settings->uid_shift = sh;
     673           0 :                 settings->uid_range = rn;
     674             :         }
     675             : 
     676           0 :         return 0;
     677             : }
     678             : 
     679           0 : int config_parse_syscall_filter(
     680             :                 const char *unit,
     681             :                 const char *filename,
     682             :                 unsigned line,
     683             :                 const char *section,
     684             :                 unsigned section_line,
     685             :                 const char *lvalue,
     686             :                 int ltype,
     687             :                 const char *rvalue,
     688             :                 void *data,
     689             :                 void *userdata) {
     690             : 
     691           0 :         Settings *settings = data;
     692             :         bool negative;
     693             :         const char *items;
     694             :         int r;
     695             : 
     696           0 :         assert(filename);
     697           0 :         assert(lvalue);
     698           0 :         assert(rvalue);
     699             : 
     700           0 :         negative = rvalue[0] == '~';
     701           0 :         items = negative ? rvalue + 1 : rvalue;
     702             : 
     703           0 :         for (;;) {
     704           0 :                 _cleanup_free_ char *word = NULL;
     705             : 
     706           0 :                 r = extract_first_word(&items, &word, NULL, 0);
     707           0 :                 if (r == 0)
     708           0 :                         break;
     709           0 :                 if (r == -ENOMEM)
     710           0 :                         return log_oom();
     711           0 :                 if (r < 0) {
     712           0 :                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse SystemCallFilter= parameter %s, ignoring: %m", rvalue);
     713           0 :                         return 0;
     714             :                 }
     715             : 
     716           0 :                 if (negative)
     717           0 :                         r = strv_extend(&settings->syscall_blacklist, word);
     718             :                 else
     719           0 :                         r = strv_extend(&settings->syscall_whitelist, word);
     720           0 :                 if (r < 0)
     721           0 :                         return log_oom();
     722             :         }
     723             : 
     724           0 :         return 0;
     725             : }
     726             : 
     727           0 : int config_parse_hostname(
     728             :                 const char *unit,
     729             :                 const char *filename,
     730             :                 unsigned line,
     731             :                 const char *section,
     732             :                 unsigned section_line,
     733             :                 const char *lvalue,
     734             :                 int ltype,
     735             :                 const char *rvalue,
     736             :                 void *data,
     737             :                 void *userdata) {
     738             : 
     739           0 :         char **s = data;
     740             : 
     741           0 :         assert(rvalue);
     742           0 :         assert(s);
     743             : 
     744           0 :         if (!hostname_is_valid(rvalue, false)) {
     745           0 :                 log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid hostname, ignoring: %s", rvalue);
     746           0 :                 return 0;
     747             :         }
     748             : 
     749           0 :         if (free_and_strdup(s, empty_to_null(rvalue)) < 0)
     750           0 :                 return log_oom();
     751             : 
     752           0 :         return 0;
     753             : }
     754             : 
     755           0 : int config_parse_oom_score_adjust(
     756             :                 const char *unit,
     757             :                 const char *filename,
     758             :                 unsigned line,
     759             :                 const char *section,
     760             :                 unsigned section_line,
     761             :                 const char *lvalue,
     762             :                 int ltype,
     763             :                 const char *rvalue,
     764             :                 void *data,
     765             :                 void *userdata) {
     766             : 
     767           0 :         Settings *settings = data;
     768             :         int oa, r;
     769             : 
     770           0 :         assert(rvalue);
     771           0 :         assert(settings);
     772             : 
     773           0 :         if (isempty(rvalue)) {
     774           0 :                 settings->oom_score_adjust_set = false;
     775           0 :                 return 0;
     776             :         }
     777             : 
     778           0 :         r = parse_oom_score_adjust(rvalue, &oa);
     779           0 :         if (r == -ERANGE) {
     780           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "OOM score adjust value out of range, ignoring: %s", rvalue);
     781           0 :                 return 0;
     782             :         }
     783           0 :         if (r < 0) {
     784           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse the OOM score adjust value, ignoring: %s", rvalue);
     785           0 :                 return 0;
     786             :         }
     787             : 
     788           0 :         settings->oom_score_adjust = oa;
     789           0 :         settings->oom_score_adjust_set = true;
     790             : 
     791           0 :         return 0;
     792             : }
     793             : 
     794           0 : int config_parse_cpu_affinity(
     795             :                 const char *unit,
     796             :                 const char *filename,
     797             :                 unsigned line,
     798             :                 const char *section,
     799             :                 unsigned section_line,
     800             :                 const char *lvalue,
     801             :                 int ltype,
     802             :                 const char *rvalue,
     803             :                 void *data,
     804             :                 void *userdata) {
     805             : 
     806           0 :         Settings *settings = data;
     807             : 
     808           0 :         assert(rvalue);
     809           0 :         assert(settings);
     810             : 
     811           0 :         return parse_cpu_set_extend(rvalue, &settings->cpu_set, true, unit, filename, line, lvalue);
     812             : }
     813             : 
     814           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_resolv_conf, resolv_conf_mode, ResolvConfMode, "Failed to parse resolv.conf mode");
     815             : 
     816             : static const char *const resolv_conf_mode_table[_RESOLV_CONF_MODE_MAX] = {
     817             :         [RESOLV_CONF_OFF] = "off",
     818             :         [RESOLV_CONF_COPY_HOST] = "copy-host",
     819             :         [RESOLV_CONF_COPY_STATIC] = "copy-static",
     820             :         [RESOLV_CONF_BIND_HOST] = "bind-host",
     821             :         [RESOLV_CONF_BIND_STATIC] = "bind-static",
     822             :         [RESOLV_CONF_DELETE] = "delete",
     823             :         [RESOLV_CONF_AUTO] = "auto",
     824             : };
     825             : 
     826          18 : DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(resolv_conf_mode, ResolvConfMode, RESOLV_CONF_AUTO);
     827             : 
     828           0 : int parse_link_journal(const char *s, LinkJournal *ret_mode, bool *ret_try) {
     829           0 :         assert(s);
     830           0 :         assert(ret_mode);
     831           0 :         assert(ret_try);
     832             : 
     833           0 :         if (streq(s, "auto")) {
     834           0 :                 *ret_mode = LINK_AUTO;
     835           0 :                 *ret_try = false;
     836           0 :         } else if (streq(s, "no")) {
     837           0 :                 *ret_mode = LINK_NO;
     838           0 :                 *ret_try = false;
     839           0 :         } else if (streq(s, "guest")) {
     840           0 :                 *ret_mode = LINK_GUEST;
     841           0 :                 *ret_try = false;
     842           0 :         } else if (streq(s, "host")) {
     843           0 :                 *ret_mode = LINK_HOST;
     844           0 :                 *ret_try = false;
     845           0 :         } else if (streq(s, "try-guest")) {
     846           0 :                 *ret_mode = LINK_GUEST;
     847           0 :                 *ret_try = true;
     848           0 :         } else if (streq(s, "try-host")) {
     849           0 :                 *ret_mode = LINK_HOST;
     850           0 :                 *ret_try = true;
     851             :         } else
     852           0 :                 return -EINVAL;
     853             : 
     854           0 :         return 0;
     855             : }
     856             : 
     857           0 : int config_parse_link_journal(
     858             :                 const char *unit,
     859             :                 const char *filename,
     860             :                 unsigned line,
     861             :                 const char *section,
     862             :                 unsigned section_line,
     863             :                 const char *lvalue,
     864             :                 int ltype,
     865             :                 const char *rvalue,
     866             :                 void *data,
     867             :                 void *userdata) {
     868             : 
     869           0 :         Settings *settings = data;
     870             :         int r;
     871             : 
     872           0 :         assert(rvalue);
     873           0 :         assert(settings);
     874             : 
     875           0 :         r = parse_link_journal(rvalue, &settings->link_journal, &settings->link_journal_try);
     876           0 :         if (r < 0) {
     877           0 :                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse link journal mode, ignoring: %s", rvalue);
     878           0 :                 return 0;
     879             :         }
     880             : 
     881           0 :         return 0;
     882             : }
     883             : 
     884           0 : DEFINE_CONFIG_PARSE_ENUM(config_parse_timezone, timezone_mode, TimezoneMode, "Failed to parse timezone mode");
     885             : 
     886             : static const char *const timezone_mode_table[_TIMEZONE_MODE_MAX] = {
     887             :         [TIMEZONE_OFF] = "off",
     888             :         [TIMEZONE_COPY] = "copy",
     889             :         [TIMEZONE_BIND] = "bind",
     890             :         [TIMEZONE_SYMLINK] = "symlink",
     891             :         [TIMEZONE_DELETE] = "delete",
     892             :         [TIMEZONE_AUTO] = "auto",
     893             : };
     894             : 
     895          16 : DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(timezone_mode, TimezoneMode, TIMEZONE_AUTO);

Generated by: LCOV version 1.14