summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-04-08 02:52:45 +0200
committerThomas Haller <thaller@redhat.com>2020-04-08 09:02:12 +0200
commitc5189cffc1b3f7d0eab75d7691c4b876cce0ba1d (patch)
tree94fe6f2a4b5cd4b8e4a733fcb721117fa66d944b
parent46a181603483fc7e5b64beef13744920560b3ef8 (diff)
downloadNetworkManager-c5189cffc1b3f7d0eab75d7691c4b876cce0ba1d.tar.gz
systemd: update code from upstream (2020-04-08)
This is a direct dump from systemd git. ====== SYSTEMD_DIR=../systemd COMMIT=8ff8ce62845e708186077d11eba83adae7b02e61 ( cd "$SYSTEMD_DIR" git checkout "$COMMIT" git reset --hard git clean -fdx ) git ls-files -z :/src/systemd/src/ \ :/shared/systemd/src/ \ :/shared/nm-std-aux/unaligned.h | \ xargs -0 rm -f nm_copy_sd_shared() { mkdir -p "./shared/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./shared/systemd/$1" } nm_copy_sd_core() { mkdir -p "./src/systemd/$(dirname "$1")" cp "$SYSTEMD_DIR/$1" "./src/systemd/$1" } nm_copy_sd_stdaux() { mkdir -p "./shared/nm-std-aux/" cp "$SYSTEMD_DIR/$1" "./shared/nm-std-aux/${1##*/}" } nm_copy_sd_core "src/libsystemd-network/arp-util.c" nm_copy_sd_core "src/libsystemd-network/arp-util.h" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.c" nm_copy_sd_core "src/libsystemd-network/dhcp-identifier.h" nm_copy_sd_core "src/libsystemd-network/dhcp-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp-packet.c" nm_copy_sd_core "src/libsystemd-network/dhcp-protocol.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-lease-internal.h" nm_copy_sd_core "src/libsystemd-network/dhcp6-network.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-option.c" nm_copy_sd_core "src/libsystemd-network/dhcp6-protocol.h" nm_copy_sd_core "src/libsystemd-network/lldp-internal.h" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.c" nm_copy_sd_core "src/libsystemd-network/lldp-neighbor.h" nm_copy_sd_core "src/libsystemd-network/lldp-network.c" nm_copy_sd_core "src/libsystemd-network/lldp-network.h" nm_copy_sd_core "src/libsystemd-network/network-internal.c" nm_copy_sd_core "src/libsystemd-network/network-internal.h" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-client.c" nm_copy_sd_core "src/libsystemd-network/sd-dhcp6-lease.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4acd.c" nm_copy_sd_core "src/libsystemd-network/sd-ipv4ll.c" nm_copy_sd_core "src/libsystemd-network/sd-lldp.c" nm_copy_sd_core "src/libsystemd/sd-event/event-source.h" nm_copy_sd_core "src/libsystemd/sd-event/event-util.c" nm_copy_sd_core "src/libsystemd/sd-event/event-util.h" nm_copy_sd_core "src/libsystemd/sd-event/sd-event.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.c" nm_copy_sd_core "src/libsystemd/sd-id128/id128-util.h" nm_copy_sd_core "src/libsystemd/sd-id128/sd-id128.c" nm_copy_sd_core "src/systemd/_sd-common.h" nm_copy_sd_core "src/systemd/sd-dhcp-client.h" nm_copy_sd_core "src/systemd/sd-dhcp-lease.h" nm_copy_sd_core "src/systemd/sd-dhcp-option.h" nm_copy_sd_core "src/systemd/sd-dhcp6-client.h" nm_copy_sd_core "src/systemd/sd-dhcp6-lease.h" nm_copy_sd_core "src/systemd/sd-event.h" nm_copy_sd_core "src/systemd/sd-id128.h" nm_copy_sd_core "src/systemd/sd-ipv4acd.h" nm_copy_sd_core "src/systemd/sd-ipv4ll.h" nm_copy_sd_core "src/systemd/sd-lldp.h" nm_copy_sd_core "src/systemd/sd-ndisc.h" nm_copy_sd_shared "src/basic/alloc-util.c" nm_copy_sd_shared "src/basic/alloc-util.h" nm_copy_sd_shared "src/basic/async.h" nm_copy_sd_shared "src/basic/cgroup-util.h" nm_copy_sd_shared "src/basic/env-file.c" nm_copy_sd_shared "src/basic/env-file.h" nm_copy_sd_shared "src/basic/env-util.c" nm_copy_sd_shared "src/basic/env-util.h" nm_copy_sd_shared "src/basic/errno-util.h" nm_copy_sd_shared "src/basic/escape.c" nm_copy_sd_shared "src/basic/escape.h" nm_copy_sd_shared "src/basic/ether-addr-util.c" nm_copy_sd_shared "src/basic/ether-addr-util.h" nm_copy_sd_shared "src/basic/extract-word.c" nm_copy_sd_shared "src/basic/extract-word.h" nm_copy_sd_shared "src/basic/fd-util.c" nm_copy_sd_shared "src/basic/fd-util.h" nm_copy_sd_shared "src/basic/fileio.c" nm_copy_sd_shared "src/basic/fileio.h" nm_copy_sd_shared "src/basic/format-util.c" nm_copy_sd_shared "src/basic/format-util.h" nm_copy_sd_shared "src/basic/fs-util.c" nm_copy_sd_shared "src/basic/fs-util.h" nm_copy_sd_shared "src/basic/hash-funcs.c" nm_copy_sd_shared "src/basic/hash-funcs.h" nm_copy_sd_shared "src/basic/hashmap.c" nm_copy_sd_shared "src/basic/hashmap.h" nm_copy_sd_shared "src/basic/hexdecoct.c" nm_copy_sd_shared "src/basic/hexdecoct.h" nm_copy_sd_shared "src/basic/hostname-util.c" nm_copy_sd_shared "src/basic/hostname-util.h" nm_copy_sd_shared "src/basic/in-addr-util.c" nm_copy_sd_shared "src/basic/in-addr-util.h" nm_copy_sd_shared "src/basic/io-util.c" nm_copy_sd_shared "src/basic/io-util.h" nm_copy_sd_shared "src/basic/list.h" nm_copy_sd_shared "src/basic/log.h" nm_copy_sd_shared "src/basic/macro.h" nm_copy_sd_shared "src/basic/memory-util.c" nm_copy_sd_shared "src/basic/memory-util.h" nm_copy_sd_shared "src/basic/mempool.c" nm_copy_sd_shared "src/basic/mempool.h" nm_copy_sd_shared "src/basic/missing_fcntl.h" nm_copy_sd_shared "src/basic/missing_random.h" nm_copy_sd_shared "src/basic/missing_socket.h" nm_copy_sd_shared "src/basic/missing_stat.h" nm_copy_sd_shared "src/basic/missing_syscall.h" nm_copy_sd_shared "src/basic/missing_type.h" nm_copy_sd_shared "src/basic/parse-util.c" nm_copy_sd_shared "src/basic/parse-util.h" nm_copy_sd_shared "src/basic/path-util.c" nm_copy_sd_shared "src/basic/path-util.h" nm_copy_sd_shared "src/basic/prioq.c" nm_copy_sd_shared "src/basic/prioq.h" nm_copy_sd_shared "src/basic/process-util.c" nm_copy_sd_shared "src/basic/process-util.h" nm_copy_sd_shared "src/basic/random-util.c" nm_copy_sd_shared "src/basic/random-util.h" nm_copy_sd_shared "src/basic/set.h" nm_copy_sd_shared "src/basic/signal-util.c" nm_copy_sd_shared "src/basic/signal-util.h" nm_copy_sd_shared "src/basic/siphash24.h" nm_copy_sd_shared "src/basic/socket-util.c" nm_copy_sd_shared "src/basic/socket-util.h" nm_copy_sd_shared "src/basic/sort-util.h" nm_copy_sd_shared "src/basic/sparse-endian.h" nm_copy_sd_shared "src/basic/stat-util.c" nm_copy_sd_shared "src/basic/stat-util.h" nm_copy_sd_shared "src/basic/stdio-util.h" nm_copy_sd_shared "src/basic/string-table.c" nm_copy_sd_shared "src/basic/string-table.h" nm_copy_sd_shared "src/basic/string-util.c" nm_copy_sd_shared "src/basic/string-util.h" nm_copy_sd_shared "src/basic/strv.c" nm_copy_sd_shared "src/basic/strv.h" nm_copy_sd_shared "src/basic/strxcpyx.c" nm_copy_sd_shared "src/basic/strxcpyx.h" nm_copy_sd_shared "src/basic/time-util.c" nm_copy_sd_shared "src/basic/time-util.h" nm_copy_sd_shared "src/basic/tmpfile-util.c" nm_copy_sd_shared "src/basic/tmpfile-util.h" nm_copy_sd_shared "src/basic/umask-util.h" nm_copy_sd_shared "src/basic/user-util.h" nm_copy_sd_shared "src/basic/utf8.c" nm_copy_sd_shared "src/basic/utf8.h" nm_copy_sd_shared "src/basic/util.c" nm_copy_sd_shared "src/basic/util.h" nm_copy_sd_shared "src/shared/dns-domain.c" nm_copy_sd_shared "src/shared/dns-domain.h" nm_copy_sd_shared "src/shared/web-util.c" nm_copy_sd_shared "src/shared/web-util.h" nm_copy_sd_stdaux "src/basic/unaligned.h"
-rw-r--r--shared/systemd/src/basic/cgroup-util.h3
-rw-r--r--shared/systemd/src/basic/fileio.c38
-rw-r--r--shared/systemd/src/basic/fileio.h3
-rw-r--r--shared/systemd/src/basic/log.h5
-rw-r--r--shared/systemd/src/basic/process-util.c37
-rw-r--r--shared/systemd/src/basic/stat-util.c4
-rw-r--r--shared/systemd/src/basic/string-util.c72
-rw-r--r--shared/systemd/src/basic/string-util.h2
-rw-r--r--shared/systemd/src/basic/strv.h10
-rw-r--r--shared/systemd/src/basic/tmpfile-util.c12
-rw-r--r--shared/systemd/src/shared/web-util.c53
-rw-r--r--shared/systemd/src/shared/web-util.h12
-rw-r--r--src/systemd/src/libsystemd-network/dhcp-lease-internal.h6
-rw-r--r--src/systemd/src/libsystemd-network/network-internal.h3
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-client.c34
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp-lease.c58
-rw-r--r--src/systemd/src/libsystemd-network/sd-dhcp6-client.c46
-rw-r--r--src/systemd/src/systemd/sd-dhcp-client.h6
-rw-r--r--src/systemd/src/systemd/sd-dhcp-lease.h2
-rw-r--r--src/systemd/src/systemd/sd-dhcp6-client.h4
20 files changed, 351 insertions, 59 deletions
diff --git a/shared/systemd/src/basic/cgroup-util.h b/shared/systemd/src/basic/cgroup-util.h
index 300555f1ac..237139fad0 100644
--- a/shared/systemd/src/basic/cgroup-util.h
+++ b/shared/systemd/src/basic/cgroup-util.h
@@ -184,10 +184,13 @@ int cg_set_attribute(const char *controller, const char *path, const char *attri
int cg_get_attribute(const char *controller, const char *path, const char *attribute, char **ret);
int cg_get_keyed_attribute(const char *controller, const char *path, const char *attribute, char **keys, char **values);
+int cg_get_attribute_as_uint64(const char *controller, const char *path, const char *attribute, uint64_t *ret);
+
int cg_set_access(const char *controller, const char *path, uid_t uid, gid_t gid);
int cg_set_xattr(const char *controller, const char *path, const char *name, const void *value, size_t size, int flags);
int cg_get_xattr(const char *controller, const char *path, const char *name, void *value, size_t size);
+int cg_get_xattr_malloc(const char *controller, const char *path, const char *name, char **ret);
int cg_remove_xattr(const char *controller, const char *path, const char *name);
int cg_install_release_agent(const char *controller, const char *agent);
diff --git a/shared/systemd/src/basic/fileio.c b/shared/systemd/src/basic/fileio.c
index fe0c4f4707..4c365ad6fa 100644
--- a/shared/systemd/src/basic/fileio.c
+++ b/shared/systemd/src/basic/fileio.c
@@ -54,6 +54,44 @@ int fdopen_unlocked(int fd, const char *options, FILE **ret) {
return 0;
}
+int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) {
+ int r;
+
+ assert(fd);
+
+ r = fdopen_unlocked(*fd, options, ret);
+ if (r < 0)
+ return r;
+
+ *fd = -1;
+
+ return 0;
+}
+
+FILE* take_fdopen(int *fd, const char *options) {
+ assert(fd);
+
+ FILE *f = fdopen(*fd, options);
+ if (!f)
+ return NULL;
+
+ *fd = -1;
+
+ return f;
+}
+
+DIR* take_fdopendir(int *dfd) {
+ assert(dfd);
+
+ DIR *d = fdopendir(*dfd);
+ if (!d)
+ return NULL;
+
+ *dfd = -1;
+
+ return d;
+}
+
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) {
FILE *f = open_memstream(ptr, sizeloc);
if (!f)
diff --git a/shared/systemd/src/basic/fileio.h b/shared/systemd/src/basic/fileio.h
index e6fea2afd4..58daabaa8f 100644
--- a/shared/systemd/src/basic/fileio.h
+++ b/shared/systemd/src/basic/fileio.h
@@ -39,6 +39,9 @@ typedef enum {
int fopen_unlocked(const char *path, const char *options, FILE **ret);
int fdopen_unlocked(int fd, const char *options, FILE **ret);
+int take_fdopen_unlocked(int *fd, const char *options, FILE **ret);
+FILE* take_fdopen(int *fd, const char *options);
+DIR* take_fdopendir(int *dfd);
FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc);
FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode);
diff --git a/shared/systemd/src/basic/log.h b/shared/systemd/src/basic/log.h
index 625be22402..2c1b00fb88 100644
--- a/shared/systemd/src/basic/log.h
+++ b/shared/systemd/src/basic/log.h
@@ -59,9 +59,12 @@ void log_show_color(bool b);
bool log_get_show_color(void) _pure_;
void log_show_location(bool b);
bool log_get_show_location(void) _pure_;
+void log_show_time(bool b);
+bool log_get_show_time(void) _pure_;
int log_show_color_from_string(const char *e);
int log_show_location_from_string(const char *e);
+int log_show_time_from_string(const char *e);
LogTarget log_get_target(void) _pure_;
int log_get_max_level_realm(LogRealm realm) _pure_;
@@ -74,7 +77,7 @@ int log_get_max_level_realm(LogRealm realm) _pure_;
*/
assert_cc(STRLEN(__FILE__) > STRLEN(RELATIVE_SOURCE_PATH) + 1);
-#define PROJECT_FILE (__FILE__ + STRLEN(RELATIVE_SOURCE_PATH) + 1)
+#define PROJECT_FILE (&__FILE__[STRLEN(RELATIVE_SOURCE_PATH) + 1])
int log_open(void);
void log_close(void);
diff --git a/shared/systemd/src/basic/process-util.c b/shared/systemd/src/basic/process-util.c
index 5de366f830..fefc2bd840 100644
--- a/shared/systemd/src/basic/process-util.c
+++ b/shared/systemd/src/basic/process-util.c
@@ -1178,6 +1178,11 @@ int must_be_root(void) {
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
}
+static void restore_sigsetp(sigset_t **ssp) {
+ if (*ssp)
+ (void) sigprocmask(SIG_SETMASK, *ssp, NULL);
+}
+
int safe_fork_full(
const char *name,
const int except_fds[],
@@ -1187,7 +1192,8 @@ int safe_fork_full(
pid_t original_pid, pid;
sigset_t saved_ss, ss;
- bool block_signals = false;
+ _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
+ bool block_signals = false, block_all = false;
int prio, r;
/* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
@@ -1202,7 +1208,7 @@ int safe_fork_full(
* be sure that SIGTERMs are not lost we might send to the child. */
assert_se(sigfillset(&ss) >= 0);
- block_signals = true;
+ block_signals = block_all = true;
} else if (flags & FORK_WAIT) {
/* Let's block SIGCHLD at least, so that we can safely watch for the child process */
@@ -1212,28 +1218,31 @@ int safe_fork_full(
block_signals = true;
}
- if (block_signals)
+ if (block_signals) {
if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0)
return log_full_errno(prio, errno, "Failed to set signal mask: %m");
+ saved_ssp = &saved_ss;
+ }
if (flags & FORK_NEW_MOUNTNS)
pid = raw_clone(SIGCHLD|CLONE_NEWNS);
else
pid = fork();
- if (pid < 0) {
- r = -errno;
-
- if (block_signals) /* undo what we did above */
- (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
-
- return log_full_errno(prio, r, "Failed to fork: %m");
- }
+ if (pid < 0)
+ return log_full_errno(prio, errno, "Failed to fork: %m");
if (pid > 0) {
/* We are in the parent process */
log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
if (flags & FORK_WAIT) {
+ if (block_all) {
+ /* undo everything except SIGCHLD */
+ ss = saved_ss;
+ assert_se(sigaddset(&ss, SIGCHLD) >= 0);
+ (void) sigprocmask(SIG_SETMASK, &ss, NULL);
+ }
+
r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
if (r < 0)
return r;
@@ -1241,9 +1250,6 @@ int safe_fork_full(
return -EPROTO;
}
- if (block_signals) /* undo what we did above */
- (void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
-
if (ret_pid)
*ret_pid = pid;
@@ -1252,6 +1258,9 @@ int safe_fork_full(
/* We are in the child process */
+ /* Restore signal mask manually */
+ saved_ssp = NULL;
+
if (flags & FORK_REOPEN_LOG) {
/* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
log_close();
diff --git a/shared/systemd/src/basic/stat-util.c b/shared/systemd/src/basic/stat-util.c
index 8ef90e96b7..5412ccbf7d 100644
--- a/shared/systemd/src/basic/stat-util.c
+++ b/shared/systemd/src/basic/stat-util.c
@@ -10,6 +10,7 @@
#include "alloc-util.h"
#include "dirent-util.h"
#include "fd-util.h"
+#include "fileio.h"
#include "fs-util.h"
#include "macro.h"
#include "missing_fs.h"
@@ -77,10 +78,9 @@ int dir_is_empty_at(int dir_fd, const char *path) {
if (fd < 0)
return -errno;
- d = fdopendir(fd);
+ d = take_fdopendir(&fd);
if (!d)
return -errno;
- fd = -1;
FOREACH_DIRENT(de, d, return -errno)
return 0;
diff --git a/shared/systemd/src/basic/string-util.c b/shared/systemd/src/basic/string-util.c
index 8f812d7cbe..9983aa826e 100644
--- a/shared/systemd/src/basic/string-util.c
+++ b/shared/systemd/src/basic/string-util.c
@@ -113,7 +113,7 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
bool escaped = false;
int n;
- for (n=0; s[n]; n++) {
+ for (n = 0; s[n] != '\0'; n++) {
if (escaped)
escaped = false;
else if (s[n] == '\\')
@@ -122,50 +122,62 @@ static size_t strcspn_escaped(const char *s, const char *reject) {
break;
}
- /* if s ends in \, return index of previous char */
- return n - escaped;
+ return n;
}
/* Split a string into words. */
-const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags) {
+const char* split(
+ const char **state,
+ size_t *l,
+ const char *separator,
+ SplitFlags flags) {
+
const char *current;
+ assert(state);
+ assert(l);
+
+ if (!separator)
+ separator = WHITESPACE;
+
current = *state;
- if (!*current) {
- assert(**state == '\0');
+ if (*current == '\0') /* already at the end? */
return NULL;
- }
- current += strspn(current, separator);
- if (!*current) {
+ current += strspn(current, separator); /* skip leading separators */
+ if (*current == '\0') { /* at the end now? */
*state = current;
return NULL;
}
- if (flags & SPLIT_QUOTES && strchr("\'\"", *current)) {
- char quotechars[2] = {*current, '\0'};
-
- *l = strcspn_escaped(current + 1, quotechars);
- if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
- (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
- /* right quote missing or garbage at the end */
- if (flags & SPLIT_RELAX) {
- *state = current + *l + 1 + (current[*l + 1] != '\0');
- return current + 1;
+ if (FLAGS_SET(flags, SPLIT_QUOTES)) {
+
+ if (strchr(QUOTES, *current)) {
+ /* We are looking at a quote */
+ *l = strcspn_escaped(current + 1, CHAR_TO_STR(*current));
+ if (current[*l + 1] != *current ||
+ (current[*l + 2] != 0 && !strchr(separator, current[*l + 2]))) {
+ /* right quote missing or garbage at the end */
+ if (FLAGS_SET(flags, SPLIT_RELAX)) {
+ *state = current + *l + 1 + (current[*l + 1] != '\0');
+ return current + 1;
+ }
+ *state = current;
+ return NULL;
}
- *state = current;
- return NULL;
- }
- *state = current++ + *l + 2;
- } else if (flags & SPLIT_QUOTES) {
- *l = strcspn_escaped(current, separator);
- if (current[*l] && !strchr(separator, current[*l]) && !(flags & SPLIT_RELAX)) {
- /* unfinished escape */
- *state = current;
- return NULL;
+ *state = current++ + *l + 2;
+
+ } else {
+ /* We are looking at a something that is not a quote */
+ *l = strcspn_escaped(current, separator);
+ if (current[*l] && !strchr(separator, current[*l]) && !FLAGS_SET(flags, SPLIT_RELAX)) {
+ /* unfinished escape */
+ *state = current;
+ return NULL;
+ }
+ *state = current + *l;
}
- *state = current + *l;
} else {
*l = strcspn(current, separator);
*state = current + *l;
diff --git a/shared/systemd/src/basic/string-util.h b/shared/systemd/src/basic/string-util.h
index f98fbdddda..2a344b996f 100644
--- a/shared/systemd/src/basic/string-util.h
+++ b/shared/systemd/src/basic/string-util.h
@@ -112,8 +112,10 @@ typedef enum SplitFlags {
SPLIT_RELAX = 0x01 << 1,
} SplitFlags;
+/* Smelly. Do not use this anymore. Use extract_first_word() instead! */
const char* split(const char **state, size_t *l, const char *separator, SplitFlags flags);
+/* Similar, don't use this anymore */
#define FOREACH_WORD(word, length, s, state) \
_FOREACH_WORD(word, length, s, WHITESPACE, 0, state)
diff --git a/shared/systemd/src/basic/strv.h b/shared/systemd/src/basic/strv.h
index e7c2b1a604..dd3323c223 100644
--- a/shared/systemd/src/basic/strv.h
+++ b/shared/systemd/src/basic/strv.h
@@ -87,6 +87,16 @@ char **strv_parse_nulstr(const char *s, size_t l);
char **strv_split_nulstr(const char *s);
int strv_make_nulstr(char * const *l, char **p, size_t *n);
+static inline int strv_from_nulstr(char ***a, const char *nulstr) {
+ char **t;
+
+ t = strv_split_nulstr(nulstr);
+ if (!t)
+ return -ENOMEM;
+ *a = t;
+ return 0;
+}
+
bool strv_overlap(char * const *a, char * const *b) _pure_;
#define STRV_FOREACH(s, l) \
diff --git a/shared/systemd/src/basic/tmpfile-util.c b/shared/systemd/src/basic/tmpfile-util.c
index decdafb9c9..9cbca312fc 100644
--- a/shared/systemd/src/basic/tmpfile-util.c
+++ b/shared/systemd/src/basic/tmpfile-util.c
@@ -48,14 +48,12 @@ int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
* context and never shared externally, hence locking is not necessary. */
- r = fdopen_unlocked(fd, "w", &f);
+ r = take_fdopen_unlocked(&fd, "w", &f);
if (r < 0) {
(void) unlink(t);
return r;
}
- TAKE_FD(fd);
-
if (ret_f)
*ret_f = TAKE_PTR(f);
@@ -80,18 +78,16 @@ int mkostemp_safe(char *pattern) {
}
int fmkostemp_safe(char *pattern, const char *mode, FILE **ret_f) {
- int fd;
+ _cleanup_close_ int fd = -1;
FILE *f;
fd = mkostemp_safe(pattern);
if (fd < 0)
return fd;
- f = fdopen(fd, mode);
- if (!f) {
- safe_close(fd);
+ f = take_fdopen(&fd, mode);
+ if (!f)
return -errno;
- }
*ret_f = f;
return 0;
diff --git a/shared/systemd/src/shared/web-util.c b/shared/systemd/src/shared/web-util.c
new file mode 100644
index 0000000000..edf650d200
--- /dev/null
+++ b/shared/systemd/src/shared/web-util.c
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <stdbool.h>
+
+#include "string-util.h"
+#include "strv.h"
+#include "utf8.h"
+#include "web-util.h"
+
+bool http_etag_is_valid(const char *etag) {
+ if (isempty(etag))
+ return false;
+
+ if (!endswith(etag, "\""))
+ return false;
+
+ if (!STARTSWITH_SET(etag, "\"", "W/\""))
+ return false;
+
+ return true;
+}
+
+bool http_url_is_valid(const char *url) {
+ const char *p;
+
+ if (isempty(url))
+ return false;
+
+ p = STARTSWITH_SET(url, "http://", "https://");
+ if (!p)
+ return false;
+
+ if (isempty(p))
+ return false;
+
+ return ascii_is_valid(p);
+}
+
+bool documentation_url_is_valid(const char *url) {
+ const char *p;
+
+ if (isempty(url))
+ return false;
+
+ if (http_url_is_valid(url))
+ return true;
+
+ p = STARTSWITH_SET(url, "file:/", "info:", "man:");
+ if (isempty(p))
+ return false;
+
+ return ascii_is_valid(p);
+}
diff --git a/shared/systemd/src/shared/web-util.h b/shared/systemd/src/shared/web-util.h
new file mode 100644
index 0000000000..c9e67e5c0a
--- /dev/null
+++ b/shared/systemd/src/shared/web-util.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "macro.h"
+
+bool http_url_is_valid(const char *url) _pure_;
+
+bool documentation_url_is_valid(const char *url) _pure_;
+
+bool http_etag_is_valid(const char *etag);
diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
index a2d0f8bd5e..5cbebb4a34 100644
--- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
+++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h
@@ -61,6 +61,12 @@ struct sd_dhcp_lease {
struct in_addr *sip;
size_t sip_size;
+ struct in_addr *pop3_server;
+ size_t pop3_server_size;
+
+ struct in_addr *smtp_server;
+ size_t smtp_server_size;
+
struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated;
diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h
index 593bad2230..16ff173ac6 100644
--- a/src/systemd/src/libsystemd-network/network-internal.h
+++ b/src/systemd/src/libsystemd-network/network-internal.h
@@ -8,7 +8,6 @@
#include "sd-dhcp-lease.h"
#include "conf-parser.h"
-#include "def.h"
#include "set.h"
#include "strv.h"
@@ -66,5 +65,3 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
-
-#define NETWORK_DIRS ((const char* const*) CONF_PATHS_STRV("systemd/network"))
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
index 82553e79ca..a59ae4767e 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c
@@ -27,6 +27,7 @@
#include "random-util.h"
#include "string-util.h"
#include "strv.h"
+#include "web-util.h"
#define MAX_CLIENT_ID_LEN (sizeof(uint32_t) + MAX_DUID_LEN) /* Arbitrary limit */
#define MAX_MAC_ADDR_LEN CONST_MAX(INFINIBAND_ALEN, ETH_ALEN)
@@ -83,6 +84,7 @@ struct sd_dhcp_client {
size_t client_id_len;
char *hostname;
char *vendor_class_identifier;
+ char *mudurl;
char **user_class;
uint32_t mtu;
uint32_t xid;
@@ -493,6 +495,18 @@ int sd_dhcp_client_set_vendor_class_identifier(
return free_and_strdup(&client->vendor_class_identifier, vci);
}
+int sd_dhcp_client_set_mud_url(
+ sd_dhcp_client *client,
+ const char *mudurl) {
+
+ assert_return(client, -EINVAL);
+ assert_return(mudurl, -EINVAL);
+ assert_return(strlen(mudurl) <= 255, -EINVAL);
+ assert_return(http_url_is_valid(mudurl), -EINVAL);
+
+ return free_and_strdup(&client->mudurl, mudurl);
+}
+
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const* user_class) {
@@ -895,6 +909,15 @@ static int client_send_discover(sd_dhcp_client *client) {
return r;
}
+ if (client->mudurl) {
+ r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
+ SD_DHCP_OPTION_MUD_URL,
+ strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
if (client->user_class) {
r = dhcp_option_append(&discover->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_USER_CLASS,
@@ -1032,6 +1055,16 @@ static int client_send_request(sd_dhcp_client *client) {
return r;
}
+ if (client->mudurl) {
+ r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
+ SD_DHCP_OPTION_MUD_URL,
+ strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
+
r = dhcp_option_append(&request->dhcp, optlen, &optoffset, 0,
SD_DHCP_OPTION_END, 0, NULL);
if (r < 0)
@@ -2101,6 +2134,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
free(client->req_opts);
free(client->hostname);
free(client->vendor_class_identifier);
+ free(client->mudurl);
client->user_class = strv_free(client->user_class);
ordered_hashmap_free(client->extra_options);
ordered_hashmap_free(client->vendor_options);
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
index 48e8aad8f3..1b7b6e1068 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c
@@ -129,6 +129,28 @@ int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
return (int) lease->sip_size;
}
+int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->pop3_server_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->pop3_server;
+ return (int) lease->pop3_server_size;
+}
+
+int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
+ assert_return(lease, -EINVAL);
+ assert_return(addr, -EINVAL);
+
+ if (lease->smtp_server_size <= 0)
+ return -ENODATA;
+
+ *addr = lease->smtp_server;
+ return (int) lease->smtp_server_size;
+}
+
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL);
assert_return(domainname, -EINVAL);
@@ -279,6 +301,8 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->dns);
free(lease->ntp);
free(lease->sip);
+ free(lease->pop3_server);
+ free(lease->smtp_server);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
@@ -601,6 +625,18 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse SIP server, ignoring: %m");
break;
+ case SD_DHCP_OPTION_POP3_SERVER:
+ r = lease_parse_in_addrs(option, len, &lease->pop3_server, &lease->pop3_server_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m");
+ break;
+
+ case SD_DHCP_OPTION_SMTP_SERVER:
+ r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
+ break;
+
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
@@ -1037,6 +1073,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*dns = NULL,
*ntp = NULL,
*sip = NULL,
+ *pop3_server = NULL,
+ *smtp_server = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
@@ -1066,6 +1104,8 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"DNS", &dns,
"NTP", &ntp,
"SIP", &sip,
+ "POP3_SERVERS", &pop3_server,
+ "SMTP_SERVERS", &smtp_server,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
@@ -1175,7 +1215,23 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
if (r < 0)
log_debug_errno(r, "Failed to deserialize SIP servers %s, ignoring: %m", sip);
else
- lease->ntp_size = r;
+ lease->sip_size = r;
+ }
+
+ if (pop3_server) {
+ r = deserialize_in_addrs(&lease->pop3_server, pop3_server);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize POP3 server %s, ignoring: %m", pop3_server);
+ else
+ lease->pop3_server_size = r;
+ }
+
+ if (smtp_server) {
+ r = deserialize_in_addrs(&lease->smtp_server, smtp_server);
+ if (r < 0)
+ log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server);
+ else
+ lease->smtp_server_size = r;
}
if (mtu) {
diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
index eac2e725cc..3f6caedfdf 100644
--- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c
@@ -25,6 +25,7 @@
#include "socket-util.h"
#include "string-table.h"
#include "util.h"
+#include "web-util.h"
#define MAX_MAC_ADDR_LEN INFINIBAND_ALEN
@@ -65,6 +66,7 @@ struct sd_dhcp6_client {
size_t req_opts_allocated;
size_t req_opts_len;
char *fqdn;
+ char *mudurl;
sd_event_source *receive_message;
usec_t retransmit_time;
uint8_t retransmit_count;
@@ -363,6 +365,17 @@ int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client, uint16_t option)
return 0;
}
+int sd_dhcp6_client_set_request_mud_url(sd_dhcp6_client *client, char *mudurl) {
+
+ assert_return(client, -EINVAL);
+ assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
+ assert_return(mudurl, -EINVAL);
+ assert_return(strlen(mudurl) <= 255, -EINVAL);
+ assert_return(http_url_is_valid(mudurl), -EINVAL);
+
+ return free_and_strdup(&client->mudurl, mudurl);
+}
+
int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
assert_return(client, -EINVAL);
assert_return(delegation, -EINVAL);
@@ -484,6 +497,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
case DHCP6_STATE_INFORMATION_REQUEST:
message->type = DHCP6_INFORMATION_REQUEST;
+ if (client->mudurl) {
+ r = dhcp6_option_append(&opt, &optlen,
+ SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
break;
case DHCP6_STATE_SOLICITATION:
@@ -507,6 +528,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->mudurl) {
+ r = dhcp6_option_append(&opt, &optlen,
+ SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->ia_pd, &client->hint_pd_prefix);
if (r < 0)
@@ -545,6 +574,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->mudurl) {
+ r = dhcp6_option_append(&opt, &optlen,
+ SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
@@ -571,6 +608,14 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
return r;
}
+ if (client->mudurl) {
+ r = dhcp6_option_append(&opt, &optlen,
+ SD_DHCP6_OPTION_MUD_URL, strlen(client->mudurl),
+ client->mudurl);
+ if (r < 0)
+ return r;
+ }
+
if (FLAGS_SET(client->request, DHCP6_REQUEST_IA_PD)) {
r = dhcp6_option_append_pd(opt, optlen, &client->lease->pd, NULL);
if (r < 0)
@@ -1521,6 +1566,7 @@ static sd_dhcp6_client *dhcp6_client_free(sd_dhcp6_client *client) {
free(client->req_opts);
free(client->fqdn);
+ free(client->mudurl);
return mfree(client);
}
diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h
index 9dd562fa43..da2aa6c73b 100644
--- a/src/systemd/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/src/systemd/sd-dhcp-client.h
@@ -83,6 +83,8 @@ enum {
SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
+ SD_DHCP_OPTION_SMTP_SERVER = 69,
+ SD_DHCP_OPTION_POP3_SERVER = 70,
SD_DHCP_OPTION_USER_CLASS = 77,
SD_DHCP_OPTION_FQDN = 81,
SD_DHCP_OPTION_NEW_POSIX_TIMEZONE = 100,
@@ -90,6 +92,7 @@ enum {
SD_DHCP_OPTION_DOMAIN_SEARCH_LIST = 119,
SD_DHCP_OPTION_SIP_SERVER = 120,
SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE = 121,
+ SD_DHCP_OPTION_MUD_URL = 161,
SD_DHCP_OPTION_PRIVATE_BASE = 224,
/* Windows 10 option to send when Anonymize=true */
SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,
@@ -169,6 +172,9 @@ int sd_dhcp_client_set_hostname(
int sd_dhcp_client_set_vendor_class_identifier(
sd_dhcp_client *client,
const char *vci);
+int sd_dhcp_client_set_mud_url(
+ sd_dhcp_client *client,
+ const char *mudurl);
int sd_dhcp_client_set_user_class(
sd_dhcp_client *client,
const char* const *user_class);
diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h
index b80d607fea..1ed5bf27a3 100644
--- a/src/systemd/src/systemd/sd-dhcp-lease.h
+++ b/src/systemd/src/systemd/sd-dhcp-lease.h
@@ -45,6 +45,8 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
+int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr);
+int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h
index be34d43e74..42d4ec752c 100644
--- a/src/systemd/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/src/systemd/sd-dhcp6-client.h
@@ -73,6 +73,7 @@ enum {
SD_DHCP6_OPTION_FQDN = 39, /* RFC 4704 */
SD_DHCP6_OPTION_NTP_SERVER = 56, /* RFC 5908 */
+ SD_DHCP6_OPTION_MUD_URL = 112, /* RFC 8250 */
/* option codes 89-142 are unassigned */
/* option codes 144-65535 are unassigned */
@@ -120,6 +121,9 @@ int sd_dhcp6_client_get_information_request(
int sd_dhcp6_client_set_request_option(
sd_dhcp6_client *client,
uint16_t option);
+int sd_dhcp6_client_set_request_mud_url(
+ sd_dhcp6_client *client,
+ char *mudurl);
int sd_dhcp6_client_set_prefix_delegation_hint(
sd_dhcp6_client *client,
uint8_t prefixlen,