mirror of
https://github.com/systemd/systemd
synced 2026-04-09 08:34:50 +02:00
Compare commits
20 Commits
8fb444011e
...
8e560cd090
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e560cd090 | ||
|
|
08e70b4a21 | ||
|
|
0289441e09 | ||
|
|
c29e6a9530 | ||
|
|
081f44859a | ||
|
|
55dad038b2 | ||
|
|
0446921131 | ||
|
|
83de7427dc | ||
|
|
13c02e7bd5 | ||
|
|
b707e43d33 | ||
|
|
46c31852f1 | ||
|
|
de045939ad | ||
|
|
1f65aa3a58 | ||
|
|
0843ec6c44 | ||
|
|
dfd0a5f127 | ||
|
|
2ab60af29d | ||
|
|
2e62139a21 | ||
|
|
5656ff9dd1 | ||
|
|
ee5b48341e | ||
|
|
3b60ededae |
@ -561,6 +561,10 @@ evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:*
|
|||||||
KEYBOARD_KEY_92=brightnessdown
|
KEYBOARD_KEY_92=brightnessdown
|
||||||
KEYBOARD_KEY_97=brightnessup
|
KEYBOARD_KEY_97=brightnessup
|
||||||
|
|
||||||
|
# HP Laptop15s-eq0xxx
|
||||||
|
evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPLaptop15s-eq0*:*
|
||||||
|
KEYBOARD_KEY_9d=102nd # Greater than/Less than
|
||||||
|
|
||||||
# Elitebook
|
# Elitebook
|
||||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:*
|
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:*
|
||||||
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:*
|
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*EliteBook*:*
|
||||||
|
|||||||
@ -818,6 +818,15 @@ $ systemd-analyze verify /tmp/source:alias.service
|
|||||||
an error.</para></listitem>
|
an error.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--profile=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>With <command>security</command> <option>--offline=</option>, takes into
|
||||||
|
consideration the specified portable profile when assessing the unit(s) settings.
|
||||||
|
The profile can be passed by name, in which case the well-known system locations will
|
||||||
|
be searched, or it can be the full path to a specific drop-in file.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--threshold=<replaceable>NUMBER</replaceable></option></term>
|
<term><option>--threshold=<replaceable>NUMBER</replaceable></option></term>
|
||||||
|
|
||||||
|
|||||||
@ -145,14 +145,17 @@ _systemd_analyze() {
|
|||||||
|
|
||||||
elif __contains_word "$verb" ${VERBS[SECURITY]}; then
|
elif __contains_word "$verb" ${VERBS[SECURITY]}; then
|
||||||
if [[ $cur = -* ]]; then
|
if [[ $cur = -* ]]; then
|
||||||
comps='--help --version --no-pager --system --user -H --host -M --machine --offline --threshold --security-policy --json=off --json=pretty --json=short'
|
comps='--help --version --no-pager --system --user -H --host -M --machine --offline --threshold --security-policy --json=off --json=pretty --json=short --root --image --profile=default --profile=nonetwork --profile=strict --profile=trusted'
|
||||||
else
|
elif ! __contains_word "--offline" ${COMP_WORDS[*]}; then
|
||||||
if __contains_word "--user" ${COMP_WORDS[*]}; then
|
if __contains_word "--user" ${COMP_WORDS[*]}; then
|
||||||
mode=--user
|
mode=--user
|
||||||
else
|
else
|
||||||
mode=--system
|
mode=--system
|
||||||
fi
|
fi
|
||||||
comps=$( __get_services $mode )
|
comps=$( __get_services $mode )
|
||||||
|
else
|
||||||
|
comps="$CONFIGS $( compgen -A file -- "$cur" )"
|
||||||
|
compopt -o filenames
|
||||||
fi
|
fi
|
||||||
|
|
||||||
elif __contains_word "$verb" ${VERBS[CONDITION]}; then
|
elif __contains_word "$verb" ${VERBS[CONDITION]}; then
|
||||||
|
|||||||
@ -87,6 +87,7 @@ _arguments \
|
|||||||
'--threshold=[Set a value to compare the overall security exposure level with]: NUMBER' \
|
'--threshold=[Set a value to compare the overall security exposure level with]: NUMBER' \
|
||||||
'--security-policy=[Allow user to use customized requirements to compare unit file(s) against]: PATH' \
|
'--security-policy=[Allow user to use customized requirements to compare unit file(s) against]: PATH' \
|
||||||
'--json=[Generate a JSON output of the security analysis table]:MODE:(pretty short off)' \
|
'--json=[Generate a JSON output of the security analysis table]:MODE:(pretty short off)' \
|
||||||
|
'--profile=[Include the specified profile in the security review of the unit(s)]: PATH' \
|
||||||
'--no-pager[Do not pipe output into a pager]' \
|
'--no-pager[Do not pipe output into a pager]' \
|
||||||
'--man=[Do (not) check for existence of man pages]:BOOL:(yes no)' \
|
'--man=[Do (not) check for existence of man pages]:BOOL:(yes no)' \
|
||||||
'--generators=[Do (not) run unit generators]:BOOL:(yes no)' \
|
'--generators=[Do (not) run unit generators]:BOOL:(yes no)' \
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "bus-map-properties.h"
|
#include "bus-map-properties.h"
|
||||||
#include "bus-unit-util.h"
|
#include "bus-unit-util.h"
|
||||||
#include "bus-util.h"
|
#include "bus-util.h"
|
||||||
|
#include "copy.h"
|
||||||
#include "env-util.h"
|
#include "env-util.h"
|
||||||
#include "format-table.h"
|
#include "format-table.h"
|
||||||
#include "in-addr-prefix-util.h"
|
#include "in-addr-prefix-util.h"
|
||||||
@ -17,6 +18,7 @@
|
|||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "missing_capability.h"
|
#include "missing_capability.h"
|
||||||
#include "missing_sched.h"
|
#include "missing_sched.h"
|
||||||
|
#include "mkdir.h"
|
||||||
#include "nulstr-util.h"
|
#include "nulstr-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
@ -2646,6 +2648,7 @@ static int offline_security_checks(char **filenames,
|
|||||||
bool run_generators,
|
bool run_generators,
|
||||||
unsigned threshold,
|
unsigned threshold,
|
||||||
const char *root,
|
const char *root,
|
||||||
|
const char *profile,
|
||||||
PagerFlags pager_flags,
|
PagerFlags pager_flags,
|
||||||
JsonFormatFlags json_format_flags) {
|
JsonFormatFlags json_format_flags) {
|
||||||
|
|
||||||
@ -2682,6 +2685,13 @@ static int offline_security_checks(char **filenames,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (profile) {
|
||||||
|
/* Ensure the temporary directory is in the search path, so that we can add drop-ins. */
|
||||||
|
r = strv_extend(&m->lookup_paths.search_path, m->lookup_paths.temporary_dir);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
log_debug("Loading remaining units from the command line...");
|
log_debug("Loading remaining units from the command line...");
|
||||||
|
|
||||||
STRV_FOREACH(filename, filenames) {
|
STRV_FOREACH(filename, filenames) {
|
||||||
@ -2697,6 +2707,33 @@ static int offline_security_checks(char **filenames,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* When a portable image is analyzed, the profile is what provides a good chunk of
|
||||||
|
* the security-related settings, but they are obviously not shipped with the image.
|
||||||
|
* This allows to take them in consideration. */
|
||||||
|
if (profile) {
|
||||||
|
_cleanup_free_ char *unit_name = NULL, *dropin = NULL, *profile_path = NULL;
|
||||||
|
|
||||||
|
r = path_extract_filename(prepared, &unit_name);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
dropin = strjoin(m->lookup_paths.temporary_dir, "/", unit_name, ".d/profile.conf");
|
||||||
|
if (!dropin)
|
||||||
|
return log_oom();
|
||||||
|
(void) mkdir_parents(dropin, 0755);
|
||||||
|
|
||||||
|
if (!is_path(profile)) {
|
||||||
|
r = find_portable_profile(profile, unit_name, &profile_path);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to find portable profile %s: %m", profile);
|
||||||
|
profile = profile_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = copy_file(profile, dropin, 0, 0644, 0, 0, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to copy: %m");
|
||||||
|
}
|
||||||
|
|
||||||
k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]);
|
k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]);
|
||||||
if (k < 0) {
|
if (k < 0) {
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
@ -2725,6 +2762,7 @@ int analyze_security(sd_bus *bus,
|
|||||||
bool offline,
|
bool offline,
|
||||||
unsigned threshold,
|
unsigned threshold,
|
||||||
const char *root,
|
const char *root,
|
||||||
|
const char *profile,
|
||||||
JsonFormatFlags json_format_flags,
|
JsonFormatFlags json_format_flags,
|
||||||
PagerFlags pager_flags,
|
PagerFlags pager_flags,
|
||||||
AnalyzeSecurityFlags flags) {
|
AnalyzeSecurityFlags flags) {
|
||||||
@ -2735,7 +2773,7 @@ int analyze_security(sd_bus *bus,
|
|||||||
assert(bus);
|
assert(bus);
|
||||||
|
|
||||||
if (offline)
|
if (offline)
|
||||||
return offline_security_checks(units, policy, scope, check_man, run_generators, threshold, root, pager_flags, json_format_flags);
|
return offline_security_checks(units, policy, scope, check_man, run_generators, threshold, root, profile, pager_flags, json_format_flags);
|
||||||
|
|
||||||
if (strv_length(units) != 1) {
|
if (strv_length(units) != 1) {
|
||||||
overview_table = table_new("unit", "exposure", "predicate", "happy");
|
overview_table = table_new("unit", "exposure", "predicate", "happy");
|
||||||
|
|||||||
@ -24,6 +24,7 @@ int analyze_security(sd_bus *bus,
|
|||||||
bool offline,
|
bool offline,
|
||||||
unsigned threshold,
|
unsigned threshold,
|
||||||
const char *root,
|
const char *root,
|
||||||
|
const char *profile,
|
||||||
JsonFormatFlags json_format_flags,
|
JsonFormatFlags json_format_flags,
|
||||||
PagerFlags pager_flags,
|
PagerFlags pager_flags,
|
||||||
AnalyzeSecurityFlags flags);
|
AnalyzeSecurityFlags flags);
|
||||||
|
|||||||
@ -105,6 +105,7 @@ static usec_t arg_base_time = USEC_INFINITY;
|
|||||||
static char *arg_unit = NULL;
|
static char *arg_unit = NULL;
|
||||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||||
static bool arg_quiet = false;
|
static bool arg_quiet = false;
|
||||||
|
static char *arg_profile = NULL;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
|
||||||
@ -112,6 +113,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
|||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_unit, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_unit, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_profile, freep);
|
||||||
|
|
||||||
typedef struct BootTimes {
|
typedef struct BootTimes {
|
||||||
usec_t firmware_time;
|
usec_t firmware_time;
|
||||||
@ -2423,6 +2425,7 @@ static int do_security(int argc, char *argv[], void *userdata) {
|
|||||||
arg_offline,
|
arg_offline,
|
||||||
arg_threshold,
|
arg_threshold,
|
||||||
arg_root,
|
arg_root,
|
||||||
|
arg_profile,
|
||||||
arg_json_format_flags,
|
arg_json_format_flags,
|
||||||
arg_pager_flags,
|
arg_pager_flags,
|
||||||
/*flags=*/ 0);
|
/*flags=*/ 0);
|
||||||
@ -2497,6 +2500,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
|||||||
" --iterations=N Show the specified number of iterations\n"
|
" --iterations=N Show the specified number of iterations\n"
|
||||||
" --base-time=TIMESTAMP Calculate calendar times relative to\n"
|
" --base-time=TIMESTAMP Calculate calendar times relative to\n"
|
||||||
" specified time\n"
|
" specified time\n"
|
||||||
|
" --profile=name|PATH Include the specified profile in the\n"
|
||||||
|
" security review of the unit(s)\n"
|
||||||
" -h --help Show this help\n"
|
" -h --help Show this help\n"
|
||||||
" --version Show package version\n"
|
" --version Show package version\n"
|
||||||
" -q --quiet Do not emit hints\n"
|
" -q --quiet Do not emit hints\n"
|
||||||
@ -2536,6 +2541,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_THRESHOLD,
|
ARG_THRESHOLD,
|
||||||
ARG_SECURITY_POLICY,
|
ARG_SECURITY_POLICY,
|
||||||
ARG_JSON,
|
ARG_JSON,
|
||||||
|
ARG_PROFILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@ -2565,6 +2571,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "base-time", required_argument, NULL, ARG_BASE_TIME },
|
{ "base-time", required_argument, NULL, ARG_BASE_TIME },
|
||||||
{ "unit", required_argument, NULL, 'U' },
|
{ "unit", required_argument, NULL, 'U' },
|
||||||
{ "json", required_argument, NULL, ARG_JSON },
|
{ "json", required_argument, NULL, ARG_JSON },
|
||||||
|
{ "profile", required_argument, NULL, ARG_PROFILE },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2713,6 +2720,24 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_PROFILE:
|
||||||
|
if (isempty(optarg))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Profile file name is empty");
|
||||||
|
|
||||||
|
if (is_path(optarg)) {
|
||||||
|
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_profile);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (!endswith(arg_profile, ".conf"))
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Profile file name must end with .conf: %s", arg_profile);
|
||||||
|
} else {
|
||||||
|
r = free_and_strdup(&arg_profile, optarg);
|
||||||
|
if (r < 0)
|
||||||
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case 'U': {
|
case 'U': {
|
||||||
_cleanup_free_ char *mangled = NULL;
|
_cleanup_free_ char *mangled = NULL;
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
#include "nulstr-util.h"
|
||||||
#include "path-lookup.h"
|
#include "path-lookup.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
@ -864,3 +865,30 @@ char **env_generator_binary_paths(bool is_system) {
|
|||||||
|
|
||||||
return TAKE_PTR(paths);
|
return TAKE_PTR(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int find_portable_profile(const char *name, const char *unit, char **ret_path) {
|
||||||
|
const char *p, *dot;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(ret_path);
|
||||||
|
|
||||||
|
assert_se(dot = strrchr(unit, '.'));
|
||||||
|
|
||||||
|
NULSTR_FOREACH(p, PORTABLE_PROFILE_DIRS) {
|
||||||
|
_cleanup_free_ char *joined = NULL;
|
||||||
|
|
||||||
|
joined = strjoin(p, "/", name, "/", dot + 1, ".conf");
|
||||||
|
if (!joined)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (laccess(joined, F_OK) >= 0) {
|
||||||
|
*ret_path = TAKE_PTR(joined);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno != ENOENT)
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
|||||||
@ -72,3 +72,6 @@ char **env_generator_binary_paths(bool is_system);
|
|||||||
|
|
||||||
#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
|
#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
|
||||||
#define NETWORK_DIRS_NULSTR CONF_PATHS_NULSTR("systemd/network")
|
#define NETWORK_DIRS_NULSTR CONF_PATHS_NULSTR("systemd/network")
|
||||||
|
|
||||||
|
#define PORTABLE_PROFILE_DIRS CONF_PATHS_NULSTR("systemd/portable/profile")
|
||||||
|
int find_portable_profile(const char *name, const char *unit, char **ret_path);
|
||||||
|
|||||||
@ -66,8 +66,7 @@ static void hash_once(
|
|||||||
struct sha256_ctx hash;
|
struct sha256_ctx hash;
|
||||||
|
|
||||||
assert(old_seed);
|
assert(old_seed);
|
||||||
assert(rng);
|
assert(system_token_size == 0 || system_token);
|
||||||
assert(system_token);
|
|
||||||
|
|
||||||
sha256_init_ctx(&hash);
|
sha256_init_ctx(&hash);
|
||||||
sha256_process_bytes(old_seed, size, &hash);
|
sha256_process_bytes(old_seed, size, &hash);
|
||||||
@ -92,8 +91,7 @@ static EFI_STATUS hash_many(
|
|||||||
_cleanup_freepool_ void *output = NULL;
|
_cleanup_freepool_ void *output = NULL;
|
||||||
|
|
||||||
assert(old_seed);
|
assert(old_seed);
|
||||||
assert(rng);
|
assert(system_token_size == 0 || system_token);
|
||||||
assert(system_token);
|
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
/* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the
|
/* Hashes the specified parameters in counter mode, generating n hash values, with the counter in the
|
||||||
@ -127,8 +125,7 @@ static EFI_STATUS mangle_random_seed(
|
|||||||
UINTN n;
|
UINTN n;
|
||||||
|
|
||||||
assert(old_seed);
|
assert(old_seed);
|
||||||
assert(rng);
|
assert(system_token_size == 0 || system_token);
|
||||||
assert(system_token);
|
|
||||||
assert(ret_new_seed);
|
assert(ret_new_seed);
|
||||||
assert(ret_for_kernel);
|
assert(ret_for_kernel);
|
||||||
|
|
||||||
|
|||||||
@ -1840,9 +1840,18 @@ static bool mount_is_mounted(Mount *m) {
|
|||||||
|
|
||||||
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
|
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
|
||||||
Manager *m = userdata;
|
Manager *m = userdata;
|
||||||
|
Job *j;
|
||||||
|
|
||||||
assert(m);
|
assert(m);
|
||||||
|
|
||||||
|
/* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */
|
||||||
|
HASHMAP_FOREACH(j, m->jobs) {
|
||||||
|
if (j->unit->type != UNIT_MOUNT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
job_add_to_run_queue(j);
|
||||||
|
}
|
||||||
|
|
||||||
/* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so
|
/* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so
|
||||||
* let's make sure we dispatch them in the next iteration. */
|
* let's make sure we dispatch them in the next iteration. */
|
||||||
manager_trigger_run_queue(m);
|
manager_trigger_run_queue(m);
|
||||||
|
|||||||
@ -817,7 +817,7 @@ int dhcp6_option_parse_ia(
|
|||||||
/* Ignore the sub-option on non-critical errors. */
|
/* Ignore the sub-option on non-critical errors. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lt_min = MIN(lt_min, a->iaaddr.lifetime_valid);
|
lt_min = MIN(lt_min, be32toh(a->iaaddr.lifetime_valid));
|
||||||
LIST_PREPEND(addresses, ia.addresses, a);
|
LIST_PREPEND(addresses, ia.addresses, a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -836,7 +836,7 @@ int dhcp6_option_parse_ia(
|
|||||||
/* Ignore the sub-option on non-critical errors. */
|
/* Ignore the sub-option on non-critical errors. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lt_min = MIN(lt_min, a->iapdprefix.lifetime_valid);
|
lt_min = MIN(lt_min, be32toh(a->iapdprefix.lifetime_valid));
|
||||||
LIST_PREPEND(addresses, ia.addresses, a);
|
LIST_PREPEND(addresses, ia.addresses, a);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,12 +105,13 @@ int sd_dhcp_lease_get_servers(
|
|||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(what >= 0, -EINVAL);
|
assert_return(what >= 0, -EINVAL);
|
||||||
assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL);
|
assert_return(what < _SD_DHCP_LEASE_SERVER_TYPE_MAX, -EINVAL);
|
||||||
assert_return(addr, -EINVAL);
|
|
||||||
|
|
||||||
if (lease->servers[what].size <= 0)
|
if (lease->servers[what].size <= 0)
|
||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
*addr = lease->servers[what].addr;
|
if (addr)
|
||||||
|
*addr = lease->servers[what].addr;
|
||||||
|
|
||||||
return (int) lease->servers[what].size;
|
return (int) lease->servers[what].size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -239,12 +239,13 @@ int dhcp6_lease_add_dns(sd_dhcp6_lease *lease, const uint8_t *optval, size_t opt
|
|||||||
|
|
||||||
int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
|
int sd_dhcp6_lease_get_dns(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
|
||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
|
|
||||||
if (!lease->dns)
|
if (!lease->dns)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
*ret = lease->dns;
|
if (ret)
|
||||||
|
*ret = lease->dns;
|
||||||
|
|
||||||
return lease->dns_count;
|
return lease->dns_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,16 +338,17 @@ int dhcp6_lease_add_sntp(sd_dhcp6_lease *lease, const uint8_t *optval, size_t op
|
|||||||
|
|
||||||
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
|
int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **ret) {
|
||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
|
|
||||||
if (lease->ntp) {
|
if (lease->ntp) {
|
||||||
*ret = lease->ntp;
|
if (ret)
|
||||||
|
*ret = lease->ntp;
|
||||||
return lease->ntp_count;
|
return lease->ntp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lease->sntp && !lease->ntp_fqdn) {
|
if (lease->sntp && !lease->ntp_fqdn) {
|
||||||
/* Fallback to the deprecated SNTP option. */
|
/* Fallback to the deprecated SNTP option. */
|
||||||
*ret = lease->sntp;
|
if (ret)
|
||||||
|
*ret = lease->sntp;
|
||||||
return lease->sntp_count;
|
return lease->sntp_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,12 +357,12 @@ int sd_dhcp6_lease_get_ntp_addrs(sd_dhcp6_lease *lease, const struct in6_addr **
|
|||||||
|
|
||||||
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
|
int sd_dhcp6_lease_get_ntp_fqdn(sd_dhcp6_lease *lease, char ***ret) {
|
||||||
assert_return(lease, -EINVAL);
|
assert_return(lease, -EINVAL);
|
||||||
assert_return(ret, -EINVAL);
|
|
||||||
|
|
||||||
if (!lease->ntp_fqdn)
|
if (!lease->ntp_fqdn)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
*ret = lease->ntp_fqdn;
|
if (ret)
|
||||||
|
*ret = lease->ntp_fqdn;
|
||||||
return strv_length(lease->ntp_fqdn);
|
return strv_length(lease->ntp_fqdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <linux/nexthop.h>
|
#include <linux/nexthop.h>
|
||||||
|
|
||||||
|
#include "dns-domain.h"
|
||||||
#include "ip-protocol-list.h"
|
#include "ip-protocol-list.h"
|
||||||
#include "netif-util.h"
|
#include "netif-util.h"
|
||||||
#include "networkd-address.h"
|
#include "networkd-address.h"
|
||||||
@ -462,7 +463,15 @@ static int network_build_json(Network *network, JsonVariant **ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return json_build(ret, JSON_BUILD_OBJECT(
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
JSON_BUILD_PAIR_STRING("NetworkFile", network->filename)));
|
JSON_BUILD_PAIR_STRING("NetworkFile", network->filename),
|
||||||
|
JSON_BUILD_PAIR_BOOLEAN("RequiredForOnline", network->required_for_online),
|
||||||
|
JSON_BUILD_PAIR("RequiredOperationalStateForOnline",
|
||||||
|
JSON_BUILD_ARRAY(JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.min)),
|
||||||
|
JSON_BUILD_STRING(link_operstate_to_string(network->required_operstate_for_online.max)))),
|
||||||
|
JSON_BUILD_PAIR_STRING("RequiredFamilyForOnline",
|
||||||
|
link_required_address_family_to_string(network->required_family_for_online)),
|
||||||
|
JSON_BUILD_PAIR_STRING("ActivationPolicy",
|
||||||
|
activation_policy_to_string(network->activation_policy))));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int device_build_json(sd_device *device, JsonVariant **ret) {
|
static int device_build_json(sd_device *device, JsonVariant **ret) {
|
||||||
@ -491,6 +500,657 @@ static int device_build_json(sd_device *device, JsonVariant **ret) {
|
|||||||
JSON_BUILD_PAIR_STRING_NON_EMPTY("Model", model)));
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("Model", model)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dns_build_json_one(Link *link, const struct in_addr_full *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) {
|
||||||
|
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(a);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (a->ifindex != 0 && a->ifindex != link->ifindex) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(&v, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_INTEGER("Family", a->family),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR("Address", &a->address, a->family),
|
||||||
|
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("Port", a->port),
|
||||||
|
JSON_BUILD_PAIR_CONDITION(a->ifindex != 0, "InterfaceIndex", JSON_BUILD_INTEGER(a->ifindex)),
|
||||||
|
JSON_BUILD_PAIR_STRING_NON_EMPTY("ServerName", a->server_name),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, a->family)));
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(v);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dns_build_json(Link *link, JsonVariant **ret) {
|
||||||
|
JsonVariant **elements = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->n_dns != UINT_MAX) {
|
||||||
|
for (unsigned i = 0; i < link->n_dns; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dns_build_json_one(link, link->dns[i], NETWORK_CONFIG_SOURCE_RUNTIME, NULL, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned i = 0; i < link->network->n_dns; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dns_build_json_one(link, link->network->dns[i], NETWORK_CONFIG_SOURCE_STATIC, NULL, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp_lease && link->network->dhcp_use_dns) {
|
||||||
|
const struct in_addr *dns;
|
||||||
|
union in_addr_union s;
|
||||||
|
int n_dns;
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n_dns = sd_dhcp_lease_get_dns(link->dhcp_lease, &dns);
|
||||||
|
for (int i = 0; i < n_dns; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dns_build_json_one(link,
|
||||||
|
&(struct in_addr_full) { .family = AF_INET, .address.in = dns[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP4,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_lease && link->network->dhcp6_use_dns) {
|
||||||
|
const struct in6_addr *dns;
|
||||||
|
union in_addr_union s;
|
||||||
|
int n_dns;
|
||||||
|
|
||||||
|
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n_dns = sd_dhcp6_lease_get_dns(link->dhcp6_lease, &dns);
|
||||||
|
for (int i = 0; i < n_dns; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dns_build_json_one(link,
|
||||||
|
&(struct in_addr_full) { .family = AF_INET6, .address.in6 = dns[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->network->ipv6_accept_ra_use_dns) {
|
||||||
|
NDiscRDNSS *a;
|
||||||
|
|
||||||
|
SET_FOREACH(a, link->ndisc_rdnss) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = dns_build_json_one(link,
|
||||||
|
&(struct in_addr_full) { .family = AF_INET6, .address.in6 = a->address, },
|
||||||
|
NETWORK_CONFIG_SOURCE_NDISC,
|
||||||
|
&(union in_addr_union) { .in6 = a->router },
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
*ret = NULL;
|
||||||
|
r = 0;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNS", JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_build_json_one_addr(int family, const union in_addr_union *a, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) {
|
||||||
|
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||||
|
assert(a);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_INTEGER("Family", family),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR("Address", a, family),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_build_json_one_fqdn(int family, const char *fqdn, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) {
|
||||||
|
assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
|
||||||
|
assert(fqdn);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("Server", fqdn),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_build_json_one_string(const char *str, NetworkConfigSource s, JsonVariant **ret) {
|
||||||
|
union in_addr_union a;
|
||||||
|
int family;
|
||||||
|
|
||||||
|
assert(str);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (in_addr_from_string_auto(str, &family, &a) >= 0)
|
||||||
|
return server_build_json_one_addr(family, &a, s, NULL, ret);
|
||||||
|
|
||||||
|
return server_build_json_one_fqdn(AF_UNSPEC, str, s, NULL, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ntp_build_json(Link *link, JsonVariant **ret) {
|
||||||
|
JsonVariant **elements;
|
||||||
|
size_t n = 0;
|
||||||
|
char **p;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STRV_FOREACH(p, link->ntp ?: link->network->ntp) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = server_build_json_one_string(*p, NETWORK_CONFIG_SOURCE_RUNTIME, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!link->ntp) {
|
||||||
|
if (link->dhcp_lease && link->network->dhcp_use_ntp) {
|
||||||
|
const struct in_addr *ntp;
|
||||||
|
union in_addr_union s;
|
||||||
|
int n_ntp;
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n_ntp = sd_dhcp_lease_get_ntp(link->dhcp_lease, &ntp);
|
||||||
|
for (int i = 0; i < n_ntp; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = server_build_json_one_addr(AF_INET,
|
||||||
|
&(union in_addr_union) { .in = ntp[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP4,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_lease && link->network->dhcp6_use_ntp) {
|
||||||
|
const struct in6_addr *ntp_addr;
|
||||||
|
union in_addr_union s;
|
||||||
|
char **ntp_fqdn;
|
||||||
|
int n_ntp;
|
||||||
|
|
||||||
|
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n_ntp = sd_dhcp6_lease_get_ntp_addrs(link->dhcp6_lease, &ntp_addr);
|
||||||
|
for (int i = 0; i < n_ntp; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = server_build_json_one_addr(AF_INET6,
|
||||||
|
&(union in_addr_union) { .in6 = ntp_addr[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_ntp = sd_dhcp6_lease_get_ntp_fqdn(link->dhcp6_lease, &ntp_fqdn);
|
||||||
|
for (int i = 0; i < n_ntp; i++) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = server_build_json_one_fqdn(AF_INET6,
|
||||||
|
ntp_fqdn[i],
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("NTP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int sip_build_json(Link *link, JsonVariant **ret) {
|
||||||
|
const struct in_addr *sip;
|
||||||
|
JsonVariant **elements;
|
||||||
|
union in_addr_union s;
|
||||||
|
size_t n = 0;
|
||||||
|
int n_sip, r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network || !link->network->dhcp_use_sip || !link->dhcp_lease) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
n_sip = sd_dhcp_lease_get_sip(link->dhcp_lease, &sip);
|
||||||
|
if (n_sip <= 0) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
elements = new(JsonVariant*, n_sip);
|
||||||
|
if (!elements)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (int i = 0; i < n_sip; i++) {
|
||||||
|
r = server_build_json_one_addr(AF_INET,
|
||||||
|
&(union in_addr_union) { .in = sip[i], },
|
||||||
|
NETWORK_CONFIG_SOURCE_DHCP4,
|
||||||
|
&s,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
if (r > 0)
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("SIP", JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int domain_build_json(int family, const char *domain, NetworkConfigSource s, const union in_addr_union *p, JsonVariant **ret) {
|
||||||
|
assert(IN_SET(family, AF_UNSPEC, AF_INET, AF_INET6));
|
||||||
|
assert(domain);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("Domain", domain),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s)),
|
||||||
|
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ConfigProvider", p, family)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int domains_build_json(Link *link, bool is_route, JsonVariant **ret) {
|
||||||
|
OrderedSet *link_domains, *network_domains;
|
||||||
|
JsonVariant **elements = NULL;
|
||||||
|
DHCPUseDomains use_domains;
|
||||||
|
union in_addr_union s;
|
||||||
|
char **p, **domains;
|
||||||
|
const char *domain;
|
||||||
|
size_t n = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
link_domains = is_route ? link->route_domains : link->search_domains;
|
||||||
|
network_domains = is_route ? link->network->route_domains : link->network->search_domains;
|
||||||
|
use_domains = is_route ? DHCP_USE_DOMAINS_ROUTE : DHCP_USE_DOMAINS_YES;
|
||||||
|
|
||||||
|
ORDERED_SET_FOREACH(domain, link_domains ?: network_domains) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = domain_build_json(AF_UNSPEC, domain,
|
||||||
|
link_domains ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC,
|
||||||
|
NULL, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!link_domains) {
|
||||||
|
if (link->dhcp_lease &&
|
||||||
|
link->network->dhcp_use_domains == use_domains) {
|
||||||
|
r = sd_dhcp_lease_get_server_identifier(link->dhcp_lease, &s.in);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domain) >= 0) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = domain_build_json(AF_INET, domain, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0) {
|
||||||
|
STRV_FOREACH(p, domains) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = domain_build_json(AF_INET, *p, NETWORK_CONFIG_SOURCE_DHCP4, &s, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->dhcp6_lease &&
|
||||||
|
link->network->dhcp6_use_domains == use_domains) {
|
||||||
|
r = sd_dhcp6_lease_get_server_address(link->dhcp6_lease, &s.in6);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0) {
|
||||||
|
STRV_FOREACH(p, domains) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = domain_build_json(AF_INET6, *p, NETWORK_CONFIG_SOURCE_DHCP6, &s, elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->network->ipv6_accept_ra_use_domains == use_domains) {
|
||||||
|
NDiscDNSSL *a;
|
||||||
|
|
||||||
|
SET_FOREACH(a, link->ndisc_dnssl) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = domain_build_json(AF_INET6, NDISC_DNSSL_DOMAIN(a), NETWORK_CONFIG_SOURCE_NDISC,
|
||||||
|
&(union in_addr_union) { .in6 = a->router },
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR(is_route ? "RouteDomains" : "SearchDomains",
|
||||||
|
JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nta_build_json(const char *nta, NetworkConfigSource s, JsonVariant **ret) {
|
||||||
|
assert(nta);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
return json_build(ret, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("DNSSECNegativeTrustAnchor", nta),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(s))));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ntas_build_json(Link *link, JsonVariant **ret) {
|
||||||
|
JsonVariant **elements = NULL;
|
||||||
|
const char *nta;
|
||||||
|
size_t n = 0;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_FOREACH(nta, link->dnssec_negative_trust_anchors ?: link->network->dnssec_negative_trust_anchors) {
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = nta_build_json(nta,
|
||||||
|
link->dnssec_negative_trust_anchors ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC,
|
||||||
|
elements + n);
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSECNegativeTrustAnchors",
|
||||||
|
JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dns_misc_build_json(Link *link, JsonVariant **ret) {
|
||||||
|
JsonVariant **elements = NULL;
|
||||||
|
ResolveSupport resolve_support;
|
||||||
|
NetworkConfigSource source;
|
||||||
|
DnsOverTlsMode mode;
|
||||||
|
size_t n = 0;
|
||||||
|
int t, r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
if (!link->network) {
|
||||||
|
*ret = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_support = link->llmnr >= 0 ? link->llmnr : link->network->llmnr;
|
||||||
|
if (resolve_support >= 0) {
|
||||||
|
source = link->llmnr >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(elements + n, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("LLMNR", resolve_support_to_string(resolve_support)),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve_support = link->mdns >= 0 ? link->mdns : link->network->mdns;
|
||||||
|
if (resolve_support >= 0) {
|
||||||
|
source = link->mdns >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(elements + n, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("MDNS", resolve_support_to_string(resolve_support)),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = link->dns_default_route >= 0 ? link->dns_default_route : link->network->dns_default_route;
|
||||||
|
if (t >= 0) {
|
||||||
|
source = link->dns_default_route >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(elements + n, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_BOOLEAN("DNSDefaultRoute", t),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mode = link->dns_over_tls_mode >= 0 ? link->dns_over_tls_mode : link->network->dns_over_tls_mode;
|
||||||
|
if (mode >= 0) {
|
||||||
|
source = link->dns_over_tls_mode >= 0 ? NETWORK_CONFIG_SOURCE_RUNTIME : NETWORK_CONFIG_SOURCE_STATIC;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(elements, n + 1)) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(elements + n, JSON_BUILD_OBJECT(
|
||||||
|
JSON_BUILD_PAIR_STRING("DNSOverTLS", dns_over_tls_mode_to_string(mode)),
|
||||||
|
JSON_BUILD_PAIR_STRING("ConfigSource", network_config_source_to_string(source))));
|
||||||
|
if (r < 0)
|
||||||
|
goto finalize;
|
||||||
|
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = json_build(ret, JSON_BUILD_OBJECT(JSON_BUILD_PAIR("DNSSettings",
|
||||||
|
JSON_BUILD_VARIANT_ARRAY(elements, n))));
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
json_variant_unref_many(elements, n);
|
||||||
|
free(elements);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int link_build_json(Link *link, JsonVariant **ret) {
|
int link_build_json(Link *link, JsonVariant **ret) {
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
|
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL, *w = NULL;
|
||||||
_cleanup_free_ char *type = NULL, *flags = NULL;
|
_cleanup_free_ char *type = NULL, *flags = NULL;
|
||||||
@ -566,6 +1226,76 @@ int link_build_json(Link *link, JsonVariant **ret) {
|
|||||||
|
|
||||||
w = json_variant_unref(w);
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = dns_build_json(link, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = ntp_build_json(link, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = sip_build_json(link, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = domains_build_json(link, /* is_route = */ false, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = domains_build_json(link, /* is_route = */ true, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = ntas_build_json(link, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
|
r = dns_misc_build_json(link, &w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = json_variant_merge(&v, w);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
w = json_variant_unref(w);
|
||||||
|
|
||||||
r = addresses_build_json(link->addresses, &w);
|
r = addresses_build_json(link->addresses, &w);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@ -195,9 +195,16 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
search_domains = ordered_set_new(&string_hash_ops_free);
|
||||||
|
if (!search_domains)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
route_domains = ordered_set_new(&string_hash_ops_free);
|
||||||
|
if (!route_domains)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
_cleanup_free_ char *str = NULL;
|
_cleanup_free_ char *str = NULL;
|
||||||
OrderedSet **domains;
|
|
||||||
const char *name;
|
const char *name;
|
||||||
int route_only;
|
int route_only;
|
||||||
|
|
||||||
@ -219,12 +226,7 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid search domain %s", name);
|
||||||
|
|
||||||
domains = route_only ? &route_domains : &search_domains;
|
r = ordered_set_consume(route_only ? route_domains : search_domains, TAKE_PTR(str));
|
||||||
r = ordered_set_ensure_allocated(domains, &string_hash_ops_free);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = ordered_set_consume(*domains, TAKE_PTR(str));
|
|
||||||
if (r == -EEXIST)
|
if (r == -EEXIST)
|
||||||
continue;
|
continue;
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@ -19,6 +19,7 @@ static const char * const network_config_source_table[_NETWORK_CONFIG_SOURCE_MAX
|
|||||||
[NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6",
|
[NETWORK_CONFIG_SOURCE_DHCP6] = "DHCPv6",
|
||||||
[NETWORK_CONFIG_SOURCE_DHCP6PD] = "DHCPv6-PD",
|
[NETWORK_CONFIG_SOURCE_DHCP6PD] = "DHCPv6-PD",
|
||||||
[NETWORK_CONFIG_SOURCE_NDISC] = "NDisc",
|
[NETWORK_CONFIG_SOURCE_NDISC] = "NDisc",
|
||||||
|
[NETWORK_CONFIG_SOURCE_RUNTIME] = "runtime",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(network_config_source, NetworkConfigSource);
|
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(network_config_source, NetworkConfigSource);
|
||||||
|
|||||||
@ -27,6 +27,7 @@ typedef enum NetworkConfigSource {
|
|||||||
NETWORK_CONFIG_SOURCE_DHCP6,
|
NETWORK_CONFIG_SOURCE_DHCP6,
|
||||||
NETWORK_CONFIG_SOURCE_DHCP6PD,
|
NETWORK_CONFIG_SOURCE_DHCP6PD,
|
||||||
NETWORK_CONFIG_SOURCE_NDISC,
|
NETWORK_CONFIG_SOURCE_NDISC,
|
||||||
|
NETWORK_CONFIG_SOURCE_RUNTIME, /* through D-Bus method */
|
||||||
_NETWORK_CONFIG_SOURCE_MAX,
|
_NETWORK_CONFIG_SOURCE_MAX,
|
||||||
_NETWORK_CONFIG_SOURCE_INVALID = -EINVAL,
|
_NETWORK_CONFIG_SOURCE_INVALID = -EINVAL,
|
||||||
} NetworkConfigSource;
|
} NetworkConfigSource;
|
||||||
|
|||||||
@ -40,8 +40,6 @@
|
|||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
|
||||||
static const char profile_dirs[] = CONF_PATHS_NULSTR("systemd/portable/profile");
|
|
||||||
|
|
||||||
/* Markers used in the first line of our 20-portable.conf unit file drop-in to determine, that a) the unit file was
|
/* Markers used in the first line of our 20-portable.conf unit file drop-in to determine, that a) the unit file was
|
||||||
* dropped there by the portable service logic and b) for which image it was dropped there. */
|
* dropped there by the portable service logic and b) for which image it was dropped there. */
|
||||||
#define PORTABLE_DROPIN_MARKER_BEGIN "# Drop-in created for image '"
|
#define PORTABLE_DROPIN_MARKER_BEGIN "# Drop-in created for image '"
|
||||||
@ -981,33 +979,6 @@ static int install_chroot_dropin(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_profile(const char *name, const char *unit, char **ret) {
|
|
||||||
const char *p, *dot;
|
|
||||||
|
|
||||||
assert(name);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
assert_se(dot = strrchr(unit, '.'));
|
|
||||||
|
|
||||||
NULSTR_FOREACH(p, profile_dirs) {
|
|
||||||
_cleanup_free_ char *joined = NULL;
|
|
||||||
|
|
||||||
joined = strjoin(p, "/", name, "/", dot + 1, ".conf");
|
|
||||||
if (!joined)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (laccess(joined, F_OK) >= 0) {
|
|
||||||
*ret = TAKE_PTR(joined);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errno != ENOENT)
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int install_profile_dropin(
|
static int install_profile_dropin(
|
||||||
const char *image_path,
|
const char *image_path,
|
||||||
const PortableMetadata *m,
|
const PortableMetadata *m,
|
||||||
@ -1028,7 +999,7 @@ static int install_profile_dropin(
|
|||||||
if (!profile)
|
if (!profile)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = find_profile(profile, m->name, &from);
|
r = find_portable_profile(profile, m->name, &from);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (r != -ENOENT)
|
if (r != -ENOENT)
|
||||||
return log_debug_errno(errno, "Profile '%s' is not accessible: %m", profile);
|
return log_debug_errno(errno, "Profile '%s' is not accessible: %m", profile);
|
||||||
@ -1790,7 +1761,7 @@ int portable_get_state(
|
|||||||
int portable_get_profiles(char ***ret) {
|
int portable_get_profiles(char ***ret) {
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
return conf_files_list_nulstr(ret, NULL, NULL, CONF_FILES_DIRECTORY|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED, profile_dirs);
|
return conf_files_list_nulstr(ret, NULL, NULL, CONF_FILES_DIRECTORY|CONF_FILES_BASENAME|CONF_FILES_FILTER_MASKED, PORTABLE_PROFILE_DIRS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const portable_change_type_table[_PORTABLE_CHANGE_TYPE_MAX] = {
|
static const char* const portable_change_type_table[_PORTABLE_CHANGE_TYPE_MAX] = {
|
||||||
|
|||||||
@ -573,7 +573,20 @@ systemd-analyze security --threshold=90 --offline=true \
|
|||||||
--security-policy=/tmp/testfile.json \
|
--security-policy=/tmp/testfile.json \
|
||||||
--root=/tmp/img/ testfile.service
|
--root=/tmp/img/ testfile.service
|
||||||
|
|
||||||
|
# The strict profile adds a lot of sanboxing options
|
||||||
|
systemd-analyze security --threshold=20 --offline=true \
|
||||||
|
--security-policy=/tmp/testfile.json \
|
||||||
|
--profile=strict \
|
||||||
|
--root=/tmp/img/ testfile.service
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
|
# The trusted profile doesn't add any sanboxing options
|
||||||
|
systemd-analyze security --threshold=20 --offline=true \
|
||||||
|
--security-policy=/tmp/testfile.json \
|
||||||
|
--profile=/usr/lib/systemd/portable/profile/trusted/service.conf \
|
||||||
|
--root=/tmp/img/ testfile.service \
|
||||||
|
&& { echo 'unexpected success'; exit 1; }
|
||||||
|
|
||||||
systemd-analyze security --threshold=50 --offline=true \
|
systemd-analyze security --threshold=50 --offline=true \
|
||||||
--security-policy=/tmp/testfile.json \
|
--security-policy=/tmp/testfile.json \
|
||||||
--root=/tmp/img/ testfile.service \
|
--root=/tmp/img/ testfile.service \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user