diff options
author | Thomas Haller <thaller@redhat.com> | 2020-04-08 02:52:45 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-04-08 09:02:12 +0200 |
commit | c5189cffc1b3f7d0eab75d7691c4b876cce0ba1d (patch) | |
tree | 94fe6f2a4b5cd4b8e4a733fcb721117fa66d944b | |
parent | 46a181603483fc7e5b64beef13744920560b3ef8 (diff) | |
download | NetworkManager-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"
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, |