mirror of
https://github.com/systemd/systemd
synced 2026-04-04 06:04:51 +02:00
Compare commits
16 Commits
a704137c20
...
84b10e536c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84b10e536c | ||
|
|
371264b6c6 | ||
|
|
126c02a8fd | ||
|
|
bb23992740 | ||
|
|
a914901d38 | ||
|
|
dfa4876c41 | ||
|
|
e44cd43788 | ||
|
|
01f6c450b6 | ||
|
|
8072a7e6a9 | ||
|
|
7d0cede04f | ||
|
|
5e659ffcb0 | ||
|
|
4ef15008cc | ||
|
|
13b7b8bd73 | ||
|
|
17193d767d | ||
|
|
ca7d208367 | ||
|
|
c990101f23 |
@ -2235,7 +2235,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
<literal>needs-reload</literal>. Package scripts may use the first to mark units for later restart when
|
||||
a new version of the package is installed. Configuration management scripts may use the second to mark
|
||||
units for a later reload when the configuration is adjusted. Those flags are not set by the manager,
|
||||
except to unset as appropriate when when the unit is stopped, restarted, or reloaded.</para>
|
||||
except to unset as appropriate when the unit is stopped, restarted, or reloaded.</para>
|
||||
|
||||
<para><varname>JobTimeoutUSec</varname> maps directly to the corresponding configuration setting in the
|
||||
unit file.</para>
|
||||
|
||||
@ -416,7 +416,7 @@
|
||||
… suffixes (to the base of 1024). If <varname>SizeMinBytes=</varname> is specified the partition is
|
||||
created at or grown to at least the specified size. If <varname>SizeMaxBytes=</varname> is specified
|
||||
the partition is created at or grown to at most the specified size. The precise size is determined
|
||||
through the weight value value configured with <varname>Weight=</varname>, see above. When
|
||||
through the weight value configured with <varname>Weight=</varname>, see above. When
|
||||
<varname>SizeMinBytes=</varname> is set equal to <varname>SizeMaxBytes=</varname> the configured
|
||||
weight has no effect as the partition is explicitly sized to the specified fixed value. Note that
|
||||
partitions are never created smaller than 4096 bytes, and since partitions are never shrunk the
|
||||
|
||||
@ -210,7 +210,7 @@
|
||||
true all connections to the server will be encrypted. Note that this
|
||||
mode requires a DNS server that supports DNS-over-TLS and has a valid
|
||||
certificate. If the hostname was specified in <varname>DNS=</varname>
|
||||
by using the format format <literal>address#server_name</literal> it
|
||||
by using the format <literal>address#server_name</literal> it
|
||||
is used to validate its certificate and also to enable Server Name
|
||||
Indication (SNI) when opening a TLS connection. Otherwise
|
||||
the certificate is checked against the server's IP.
|
||||
|
||||
@ -3163,7 +3163,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
||||
configuration, with just a few environment variables. The user manager inherits environment variables as
|
||||
any other system service, but in addition may receive additional environment variables from PAM, and,
|
||||
typically, additional imported variables when the user starts a graphical session. It is recommended to
|
||||
keep the environment blocks in both the system and user managers managers lean. Importing all variables
|
||||
keep the environment blocks in both the system and user managers lean. Importing all variables
|
||||
inherited by the graphical session or by one of the user shells is strongly discouraged.</para>
|
||||
|
||||
<para>Hint: <command>systemd-run -P env</command> and <command>systemd-run --user -P env</command> print
|
||||
|
||||
@ -128,7 +128,7 @@
|
||||
datagram. This field is only included if the <varname>MESSAGE=</varname>
|
||||
field was modified compared to the original payload or the timestamp could
|
||||
not be located properly and is not included in
|
||||
<varname>SYSLOG_TIMESTAMP=</varname>. Message truncation occurs when when
|
||||
<varname>SYSLOG_TIMESTAMP=</varname>. Message truncation occurs when
|
||||
the message contains leading or trailing whitespace (trailing and leading
|
||||
whitespace is stripped), or it contains an embedded
|
||||
<constant>NUL</constant> byte (the <constant>NUL</constant> byte and
|
||||
|
||||
@ -2558,7 +2558,7 @@ Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<para>Takes a boolean value. When <literal>yes</literal>, DHCP server socket will be bound
|
||||
to its network interface and all socket communication will be restricted to this interface.
|
||||
Defaults to <literal>yes</literal>, except if <varname>RelayTarget=</varname> is used (see below),
|
||||
in which case it defaults defaults to <literal>no</literal>.</para>
|
||||
in which case it defaults to <literal>no</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<title>Description</title>
|
||||
|
||||
<para>An nspawn container settings file (suffix <filename>.nspawn</filename>) contains runtime
|
||||
configuration for a local container, and is used used by
|
||||
configuration for a local container, and is used by
|
||||
<citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||
Files of this type are named after the containers they define settings for. They are optional, and only
|
||||
required for containers whose execution environment shall differ from the defaults. Files of this type
|
||||
|
||||
@ -146,6 +146,14 @@
|
||||
typically preferable, since it runs in a locked down sandbox.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--chain</option></term>
|
||||
|
||||
<listitem><para>When used with the <command>ssh-authorized-keys</command> command, this will allow
|
||||
passing an additional command line after the user name that is chain executed after the lookup
|
||||
completed. This allows chaining multiple tools that show SSH authorized keys.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-legend" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
@ -201,8 +209,8 @@
|
||||
<varlistentry>
|
||||
<term><command>ssh-authorized-keys</command></term>
|
||||
|
||||
<listitem><para>This operation is not a public, user-facing interface. It is used to allow the SSH daemon to pick
|
||||
up authorized keys from user records, see below.</para></listitem>
|
||||
<listitem><para>Show SSH authorized keys for this account. This command is intended to be used to
|
||||
allow the SSH daemon to pick up authorized keys from user records, see below.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
@ -301,6 +309,19 @@
|
||||
AuthorizedKeysCommand /usr/bin/userdbctl ssh-authorized-keys %u
|
||||
AuthorizedKeysCommandUser root
|
||||
…</programlisting>
|
||||
|
||||
<para>Sometimes it's useful to allow chain invocation of another program to list SSH authorized keys. By
|
||||
using the <option>--chain</option> such a tool may be chain executed by <command>userdbctl
|
||||
ssh-authorized-keys</command> once a lookup completes (regardless if an SSH key was found or
|
||||
not). Example:</para>
|
||||
|
||||
<programlisting>…
|
||||
AuthorizedKeysCommand /usr/bin/userdbctl ssh-authorized-keys %u --chain /usr/bin/othertool %u
|
||||
AuthorizedKeysCommandUser root
|
||||
…</programlisting>
|
||||
|
||||
<para>The above will first query the userdb database for SSH keys, and then chain execute
|
||||
<command>/usr/bin/othertool</command> to also be queried.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
@ -544,7 +544,7 @@ char* shell_maybe_quote(const char *s, ShellEscapeFlags flags) {
|
||||
return str_realloc(buf);
|
||||
}
|
||||
|
||||
char* quote_command_line(char **argv) {
|
||||
char* quote_command_line(char **argv, ShellEscapeFlags flags) {
|
||||
_cleanup_free_ char *result = NULL;
|
||||
|
||||
assert(argv);
|
||||
@ -553,7 +553,7 @@ char* quote_command_line(char **argv) {
|
||||
STRV_FOREACH(a, argv) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
t = shell_maybe_quote(*a, SHELL_ESCAPE_EMPTY);
|
||||
t = shell_maybe_quote(*a, flags);
|
||||
if (!t)
|
||||
return NULL;
|
||||
|
||||
@ -561,5 +561,5 @@ char* quote_command_line(char **argv) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TAKE_PTR(result);
|
||||
return str_realloc(TAKE_PTR(result));
|
||||
}
|
||||
|
||||
@ -69,4 +69,4 @@ char* escape_non_printable_full(const char *str, size_t console_width, XEscapeFl
|
||||
|
||||
char* shell_escape(const char *s, const char *bad);
|
||||
char* shell_maybe_quote(const char *s, ShellEscapeFlags flags);
|
||||
char* quote_command_line(char **argv);
|
||||
char* quote_command_line(char **argv, ShellEscapeFlags flags);
|
||||
|
||||
@ -11,7 +11,11 @@
|
||||
#include "macro.h"
|
||||
#include "string-util.h"
|
||||
|
||||
char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]) {
|
||||
char *hw_addr_to_string_full(
|
||||
const struct hw_addr_data *addr,
|
||||
HardwareAddressToStringFlags flags,
|
||||
char buffer[static HW_ADDR_TO_STRING_MAX]) {
|
||||
|
||||
assert(addr);
|
||||
assert(buffer);
|
||||
assert(addr->length <= HW_ADDR_MAX_SIZE);
|
||||
@ -19,10 +23,13 @@ char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_
|
||||
for (size_t i = 0, j = 0; i < addr->length; i++) {
|
||||
buffer[j++] = hexchar(addr->bytes[i] >> 4);
|
||||
buffer[j++] = hexchar(addr->bytes[i] & 0x0f);
|
||||
if (!FLAGS_SET(flags, HW_ADDR_TO_STRING_NO_COLON))
|
||||
buffer[j++] = ':';
|
||||
}
|
||||
|
||||
buffer[addr->length > 0 ? addr->length * 3 - 1 : 0] = '\0';
|
||||
buffer[addr->length == 0 || FLAGS_SET(flags, HW_ADDR_TO_STRING_NO_COLON) ?
|
||||
addr->length * 2 :
|
||||
addr->length * 3 - 1] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -39,7 +46,7 @@ int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b)
|
||||
return memcmp(a->bytes, b->bytes, a->length);
|
||||
}
|
||||
|
||||
static void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) {
|
||||
void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state) {
|
||||
assert(p);
|
||||
assert(state);
|
||||
|
||||
|
||||
@ -31,16 +31,28 @@ static inline int parse_hw_addr(const char *s, struct hw_addr_data *ret) {
|
||||
}
|
||||
int parse_ether_addr(const char *s, struct ether_addr *ret);
|
||||
|
||||
typedef enum HardwareAddressToStringFlags {
|
||||
HW_ADDR_TO_STRING_NO_COLON = 1 << 0,
|
||||
} HardwareAddressToStringFlags;
|
||||
|
||||
#define HW_ADDR_TO_STRING_MAX (3*HW_ADDR_MAX_SIZE)
|
||||
char* hw_addr_to_string(const struct hw_addr_data *addr, char buffer[HW_ADDR_TO_STRING_MAX]);
|
||||
char *hw_addr_to_string_full(
|
||||
const struct hw_addr_data *addr,
|
||||
HardwareAddressToStringFlags flags,
|
||||
char buffer[static HW_ADDR_TO_STRING_MAX]);
|
||||
static inline char *hw_addr_to_string(const struct hw_addr_data *addr, char buffer[static HW_ADDR_TO_STRING_MAX]) {
|
||||
return hw_addr_to_string_full(addr, 0, buffer);
|
||||
}
|
||||
|
||||
/* Note: the lifetime of the compound literal is the immediately surrounding block,
|
||||
* see C11 §6.5.2.5, and
|
||||
* https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks */
|
||||
#define HW_ADDR_TO_STR(hw_addr) hw_addr_to_string((hw_addr), (char[HW_ADDR_TO_STRING_MAX]){})
|
||||
#define HW_ADDR_TO_STR_FULL(hw_addr, flags) hw_addr_to_string_full((hw_addr), flags, (char[HW_ADDR_TO_STRING_MAX]){})
|
||||
#define HW_ADDR_TO_STR(hw_addr) HW_ADDR_TO_STR_FULL(hw_addr, 0)
|
||||
|
||||
#define HW_ADDR_NULL ((const struct hw_addr_data){})
|
||||
|
||||
void hw_addr_hash_func(const struct hw_addr_data *p, struct siphash *state);
|
||||
int hw_addr_compare(const struct hw_addr_data *a, const struct hw_addr_data *b);
|
||||
static inline bool hw_addr_equal(const struct hw_addr_data *a, const struct hw_addr_data *b) {
|
||||
return hw_addr_compare(a, b) == 0;
|
||||
|
||||
@ -219,20 +219,9 @@ int get_process_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags
|
||||
if (!args)
|
||||
return -ENOMEM;
|
||||
|
||||
for (size_t i = 0; args[i]; i++) {
|
||||
char *e;
|
||||
|
||||
e = shell_maybe_quote(args[i], shflags);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
free_and_replace(args[i], e);
|
||||
}
|
||||
|
||||
ans = strv_join(args, " ");
|
||||
ans = quote_command_line(args, shflags);
|
||||
if (!ans)
|
||||
return -ENOMEM;
|
||||
|
||||
} else {
|
||||
/* Arguments are separated by NULs. Let's replace those with spaces. */
|
||||
for (size_t i = 0; i < k - 1; i++)
|
||||
|
||||
@ -3999,16 +3999,15 @@ static int exec_child(
|
||||
exec_context_tty_reset(context, params);
|
||||
|
||||
if (unit_shall_confirm_spawn(unit)) {
|
||||
const char *vc = params->confirm_spawn;
|
||||
_cleanup_free_ char *cmdline = NULL;
|
||||
|
||||
cmdline = quote_command_line(command->argv);
|
||||
cmdline = quote_command_line(command->argv, SHELL_ESCAPE_EMPTY);
|
||||
if (!cmdline) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = ask_for_confirmation(context, vc, unit, cmdline);
|
||||
r = ask_for_confirmation(context, params->confirm_spawn, unit, cmdline);
|
||||
if (r != CONFIRM_EXECUTE) {
|
||||
if (r == CONFIRM_PRETEND_SUCCESS) {
|
||||
*exit_status = EXIT_SUCCESS;
|
||||
@ -4884,7 +4883,7 @@ static int exec_child(
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
|
||||
line = quote_command_line(final_argv);
|
||||
line = quote_command_line(final_argv, SHELL_ESCAPE_EMPTY);
|
||||
if (!line) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
@ -4976,7 +4975,7 @@ int exec_spawn(Unit *unit,
|
||||
if (r < 0)
|
||||
return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
|
||||
|
||||
line = quote_command_line(command->argv);
|
||||
line = quote_command_line(command->argv, SHELL_ESCAPE_EMPTY);
|
||||
if (!line)
|
||||
return log_oom();
|
||||
|
||||
@ -6230,7 +6229,7 @@ static void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
|
||||
prefix = strempty(prefix);
|
||||
prefix2 = strjoina(prefix, "\t");
|
||||
|
||||
cmd = quote_command_line(c->argv);
|
||||
cmd = quote_command_line(c->argv, SHELL_ESCAPE_EMPTY);
|
||||
fprintf(f,
|
||||
"%sCommand Line: %s\n",
|
||||
prefix, cmd ? cmd : strerror_safe(ENOMEM));
|
||||
|
||||
@ -968,7 +968,7 @@ int bus_socket_exec(sd_bus *b) {
|
||||
_cleanup_free_ char *line = NULL;
|
||||
|
||||
if (b->exec_argv)
|
||||
line = quote_command_line(b->exec_argv);
|
||||
line = quote_command_line(b->exec_argv, SHELL_ESCAPE_EMPTY);
|
||||
|
||||
log_debug("sd-bus: starting bus%s%s with %s%s",
|
||||
b->description ? " " : "", strempty(b->description),
|
||||
|
||||
@ -968,7 +968,7 @@ DEFINE_TYPE_SYSTEM(rtnl_route);
|
||||
|
||||
static const NLType rtnl_neigh_types[] = {
|
||||
[NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR },
|
||||
[NDA_LLADDR] = { /* struct ether_addr, struct in_addr, or struct in6_addr */ },
|
||||
[NDA_LLADDR] = { .type = NETLINK_TYPE_ETHER_ADDR },
|
||||
[NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) },
|
||||
[NDA_PROBES] = { .type = NETLINK_TYPE_U32 },
|
||||
[NDA_VLAN] = { .type = NETLINK_TYPE_U16 },
|
||||
|
||||
@ -196,11 +196,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
test_find_language_fallback();
|
||||
test_find_converted_keymap();
|
||||
test_find_legacy_keymap();
|
||||
|
||||
assert_se(get_testdata_dir("test-keymap-util/kbd-model-map", &map) >= 0);
|
||||
assert_se(setenv("SYSTEMD_KBD_MODEL_MAP", map, 1) == 0);
|
||||
|
||||
test_find_legacy_keymap();
|
||||
test_vconsole_convert_to_x11();
|
||||
test_x11_convert_to_vconsole();
|
||||
|
||||
|
||||
@ -91,7 +91,6 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
|
||||
assert(neighbor);
|
||||
|
||||
siphash24_compress(&neighbor->family, sizeof(neighbor->family), state);
|
||||
siphash24_compress(&neighbor->lladdr_size, sizeof(neighbor->lladdr_size), state);
|
||||
|
||||
switch (neighbor->family) {
|
||||
case AF_INET:
|
||||
@ -104,7 +103,7 @@ void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) {
|
||||
break;
|
||||
}
|
||||
|
||||
siphash24_compress(&neighbor->lladdr, neighbor->lladdr_size, state);
|
||||
hw_addr_hash_func(&neighbor->ll_addr, state);
|
||||
}
|
||||
|
||||
int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
|
||||
@ -114,10 +113,6 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = CMP(a->lladdr_size, b->lladdr_size);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
switch (a->family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
@ -126,7 +121,7 @@ int neighbor_compare_func(const Neighbor *a, const Neighbor *b) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return memcmp(&a->lladdr, &b->lladdr, a->lladdr_size);
|
||||
return hw_addr_compare(&a->ll_addr, &b->ll_addr);
|
||||
}
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(neighbor_hash_ops, Neighbor, neighbor_hash_func, neighbor_compare_func, neighbor_free);
|
||||
@ -163,7 +158,7 @@ static int neighbor_add(Link *link, Neighbor *neighbor) {
|
||||
}
|
||||
|
||||
static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const Link *link) {
|
||||
_cleanup_free_ char *state = NULL, *lladdr = NULL, *dst = NULL;
|
||||
_cleanup_free_ char *state = NULL, *dst = NULL;
|
||||
|
||||
assert(neighbor);
|
||||
assert(str);
|
||||
@ -172,19 +167,12 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const
|
||||
return;
|
||||
|
||||
(void) network_config_state_to_string_alloc(neighbor->state, &state);
|
||||
if (neighbor->lladdr_size == sizeof(struct ether_addr))
|
||||
(void) ether_addr_to_string_alloc(&neighbor->lladdr.mac, &lladdr);
|
||||
else if (neighbor->lladdr_size == sizeof(struct in_addr))
|
||||
(void) in_addr_to_string(AF_INET, &neighbor->lladdr.ip, &lladdr);
|
||||
else if (neighbor->lladdr_size == sizeof(struct in6_addr))
|
||||
(void) in_addr_to_string(AF_INET6, &neighbor->lladdr.ip, &lladdr);
|
||||
|
||||
(void) in_addr_to_string(neighbor->family, &neighbor->in_addr, &dst);
|
||||
|
||||
log_link_debug(link,
|
||||
"%s %s neighbor (%s): lladdr: %s, dst: %s",
|
||||
str, strna(network_config_source_to_string(neighbor->source)), strna(state),
|
||||
strna(lladdr), strna(dst));
|
||||
HW_ADDR_TO_STR(&neighbor->ll_addr), strna(dst));
|
||||
}
|
||||
|
||||
static int neighbor_configure(
|
||||
@ -213,7 +201,7 @@ static int neighbor_configure(
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set state: %m");
|
||||
|
||||
r = sd_netlink_message_append_data(req, NDA_LLADDR, &neighbor->lladdr, neighbor->lladdr_size);
|
||||
r = netlink_message_append_hw_addr(req, NDA_LLADDR, &neighbor->ll_addr);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NDA_LLADDR attribute: %m");
|
||||
|
||||
@ -466,7 +454,6 @@ int request_process_neighbor(Request *req) {
|
||||
|
||||
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(neighbor_freep) Neighbor *tmp = NULL;
|
||||
_cleanup_free_ void *lladdr = NULL;
|
||||
Neighbor *neighbor = NULL;
|
||||
uint16_t type, state;
|
||||
int ifindex, r;
|
||||
@ -536,15 +523,11 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_read_data(message, NDA_LLADDR, &tmp->lladdr_size, &lladdr);
|
||||
r = netlink_message_read_hw_addr(message, NDA_LLADDR, &tmp->ll_addr);
|
||||
if (r < 0) {
|
||||
log_link_warning_errno(link, r, "rtnl: received neighbor message without valid lladdr, ignoring: %m");
|
||||
return 0;
|
||||
} else if (!IN_SET(tmp->lladdr_size, sizeof(struct ether_addr), sizeof(struct in_addr), sizeof(struct in6_addr))) {
|
||||
log_link_warning(link, "rtnl: received neighbor message with invalid lladdr size (%zu), ignoring: %m", tmp->lladdr_size);
|
||||
log_link_warning_errno(link, r, "rtnl: received neighbor message without valid link layer address, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
memcpy(&tmp->lladdr, lladdr, tmp->lladdr_size);
|
||||
|
||||
(void) neighbor_get(link, tmp, &neighbor);
|
||||
|
||||
@ -596,7 +579,7 @@ static int neighbor_section_verify(Neighbor *neighbor) {
|
||||
"Ignoring [Neighbor] section from line %u.",
|
||||
neighbor->section->filename, neighbor->section->line);
|
||||
|
||||
if (neighbor->lladdr_size == 0)
|
||||
if (neighbor->ll_addr.length == 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s: Neighbor section without LinkLayerAddress= configured. "
|
||||
"Ignoring [Neighbor] section from line %u.",
|
||||
@ -628,20 +611,27 @@ int config_parse_neighbor_address(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL;
|
||||
Network *network = userdata;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
assert(userdata);
|
||||
|
||||
r = neighbor_new_static(network, filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->family = AF_UNSPEC;
|
||||
n->in_addr = IN_ADDR_NULL;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = in_addr_from_string_auto(rvalue, &n->family, &n->in_addr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
@ -650,7 +640,6 @@ int config_parse_neighbor_address(
|
||||
}
|
||||
|
||||
TAKE_PTR(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -666,74 +655,34 @@ int config_parse_neighbor_lladdr(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL;
|
||||
int family, r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = neighbor_new_static(network, filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = parse_ether_addr(rvalue, &n->lladdr.mac);
|
||||
if (r >= 0)
|
||||
n->lladdr_size = sizeof(n->lladdr.mac);
|
||||
else {
|
||||
r = in_addr_from_string_auto(rvalue, &family, &n->lladdr.ip);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Neighbor LinkLayerAddress= is invalid, ignoring assignment: %s",
|
||||
rvalue);
|
||||
return 0;
|
||||
}
|
||||
n->lladdr_size = family == AF_INET ? sizeof(n->lladdr.ip.in) : sizeof(n->lladdr.ip.in6);
|
||||
}
|
||||
|
||||
TAKE_PTR(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_neighbor_hwaddr(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(neighbor_free_or_set_invalidp) Neighbor *n = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
assert(userdata);
|
||||
|
||||
r = neighbor_new_static(network, filename, section_line, &n);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = parse_ether_addr(rvalue, &n->lladdr.mac);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Neighbor MACAddress= is invalid, ignoring assignment: %s", rvalue);
|
||||
if (isempty(rvalue)) {
|
||||
n->ll_addr = HW_ADDR_NULL;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->lladdr_size = sizeof(n->lladdr.mac);
|
||||
TAKE_PTR(n);
|
||||
r = parse_hw_addr(rvalue, &n->ll_addr);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Neighbor %s= is invalid, ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -15,11 +15,6 @@ typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
union lladdr_union {
|
||||
struct ether_addr mac;
|
||||
union in_addr_union ip;
|
||||
};
|
||||
|
||||
typedef struct Neighbor {
|
||||
Network *network;
|
||||
Link *link;
|
||||
@ -29,8 +24,7 @@ typedef struct Neighbor {
|
||||
|
||||
int family;
|
||||
union in_addr_union in_addr;
|
||||
union lladdr_union lladdr;
|
||||
size_t lladdr_size;
|
||||
struct hw_addr_data ll_addr;
|
||||
} Neighbor;
|
||||
|
||||
Neighbor *neighbor_free(Neighbor *neighbor);
|
||||
@ -52,5 +46,4 @@ int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Neighbor, neighbor);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_hwaddr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_lladdr);
|
||||
|
||||
@ -156,7 +156,7 @@ IPv6AddressLabel.Prefix, config_parse_address_label_prefix,
|
||||
IPv6AddressLabel.Label, config_parse_address_label, 0, 0
|
||||
Neighbor.Address, config_parse_neighbor_address, 0, 0
|
||||
Neighbor.LinkLayerAddress, config_parse_neighbor_lladdr, 0, 0
|
||||
Neighbor.MACAddress, config_parse_neighbor_hwaddr, 0, 0 /* deprecated */
|
||||
Neighbor.MACAddress, config_parse_neighbor_lladdr, 0, 0 /* deprecated */
|
||||
RoutingPolicyRule.TypeOfService, config_parse_routing_policy_rule_tos, 0, 0
|
||||
RoutingPolicyRule.Priority, config_parse_routing_policy_rule_priority, 0, 0
|
||||
RoutingPolicyRule.Table, config_parse_routing_policy_rule_table, 0, 0
|
||||
|
||||
@ -206,7 +206,7 @@ static void test_shell_maybe_quote(void) {
|
||||
static void test_quote_command_line_one(char **argv, const char *expected) {
|
||||
_cleanup_free_ char *s;
|
||||
|
||||
assert_se(s = quote_command_line(argv));
|
||||
assert_se(s = quote_command_line(argv, SHELL_ESCAPE_EMPTY));
|
||||
log_info("%s", s);
|
||||
assert_se(streq(s, expected));
|
||||
}
|
||||
|
||||
@ -957,7 +957,7 @@ static int builtin_net_id(sd_device *dev, sd_netlink **rtnl, int argc, char *arg
|
||||
if (names_mac(dev, &info) >= 0) {
|
||||
char str[ALTIFNAMSIZ];
|
||||
|
||||
xsprintf(str, "%s%s", prefix, HW_ADDR_TO_STR(&info.hw_addr));
|
||||
xsprintf(str, "%s%s", prefix, HW_ADDR_TO_STR_FULL(&info.hw_addr, HW_ADDR_TO_STRING_NO_COLON));
|
||||
udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
|
||||
|
||||
ieee_oui(dev, &info, test);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
#include "dirent-util.h"
|
||||
#include "errno-list.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-table.h"
|
||||
#include "format-util.h"
|
||||
@ -34,6 +35,7 @@ static bool arg_legend = true;
|
||||
static char** arg_services = NULL;
|
||||
static UserDBFlags arg_userdb_flags = 0;
|
||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||
static bool arg_chain = false;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_services, strv_freep);
|
||||
|
||||
@ -586,18 +588,47 @@ static int display_services(int argc, char *argv[], void *userdata) {
|
||||
|
||||
static int ssh_authorized_keys(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
char **chain_invocation;
|
||||
int r;
|
||||
|
||||
assert(argc >= 2);
|
||||
|
||||
if (arg_chain) {
|
||||
/* If --chain is specified, the rest of the command line is the chain command */
|
||||
|
||||
if (argc < 3)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"No chain command line specified, refusing.");
|
||||
|
||||
/* Make similar restrictions on the chain command as OpenSSH itself makes on the primary command. */
|
||||
if (!path_is_absolute(argv[2]))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Chain invocation of ssh-authorized-keys commands requires an absolute binary path argument.");
|
||||
|
||||
if (!path_is_normalized(argv[2]))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Chain invocation of ssh-authorized-keys commands requires an normalized binary path argument.");
|
||||
|
||||
chain_invocation = argv + 2;
|
||||
} else {
|
||||
/* If --chain is not specified, then refuse any further arguments */
|
||||
|
||||
if (argc > 2)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Too many arguments.");
|
||||
|
||||
chain_invocation = NULL;
|
||||
}
|
||||
|
||||
r = userdb_by_name(argv[1], arg_userdb_flags, &ur);
|
||||
if (r == -ESRCH)
|
||||
return log_error_errno(r, "User %s does not exist.", argv[1]);
|
||||
log_error_errno(r, "User %s does not exist.", argv[1]);
|
||||
else if (r == -EHOSTDOWN)
|
||||
return log_error_errno(r, "Selected user database service is not available for this request.");
|
||||
log_error_errno(r, "Selected user database service is not available for this request.");
|
||||
else if (r == -EINVAL)
|
||||
return log_error_errno(r, "Failed to find user %s: %m (Invalid user name?)", argv[1]);
|
||||
log_error_errno(r, "Failed to find user %s: %m (Invalid user name?)", argv[1]);
|
||||
else if (r < 0)
|
||||
return log_error_errno(r, "Failed to find user %s: %m", argv[1]);
|
||||
|
||||
log_error_errno(r, "Failed to find user %s: %m", argv[1]);
|
||||
else {
|
||||
if (strv_isempty(ur->ssh_authorized_keys))
|
||||
log_debug("User record for %s has no public SSH keys.", argv[1]);
|
||||
else {
|
||||
@ -611,8 +642,30 @@ static int ssh_authorized_keys(int argc, char *argv[], void *userdata) {
|
||||
fflush(stdout);
|
||||
log_warning("Warning: lacking rights to acquire privileged fields of user record of '%s', output incomplete.", ur->user_name);
|
||||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
if (chain_invocation) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
s = quote_command_line(chain_invocation, SHELL_ESCAPE_EMPTY);
|
||||
if (!s)
|
||||
return log_oom();
|
||||
|
||||
log_debug("Chain invoking: %s", s);
|
||||
}
|
||||
|
||||
execv(chain_invocation[0], chain_invocation);
|
||||
if (errno == ENOENT) /* Let's handle ENOENT gracefully */
|
||||
log_warning_errno(errno, "Chain executable '%s' does not exist, ignoring chain invocation.", chain_invocation[0]);
|
||||
else {
|
||||
log_error_errno(errno, "Failed to invoke chain executable '%s': %m", chain_invocation[0]);
|
||||
if (r >= 0)
|
||||
r = -errno;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int help(int argc, char *argv[], void *userdata) {
|
||||
@ -633,6 +686,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" users-in-group [GROUP…] Show users that are members of specified group(s)\n"
|
||||
" groups-of-user [USER…] Show groups the specified user(s) is a member of\n"
|
||||
" services Show enabled database services\n"
|
||||
" ssh-authorized-keys USER Show SSH authorized keys for user\n"
|
||||
"\nOptions:\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
@ -650,6 +704,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --with-varlink=BOOL Control whether to talk to services at all\n"
|
||||
" --multiplexer=BOOL Control whether to use the multiplexer\n"
|
||||
" --json=pretty|short JSON output mode\n"
|
||||
" --chain Chain another command\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
@ -672,6 +727,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_SYNTHESIZE,
|
||||
ARG_MULTIPLEXER,
|
||||
ARG_JSON,
|
||||
ARG_CHAIN,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -687,6 +743,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "synthesize", required_argument, NULL, ARG_SYNTHESIZE },
|
||||
{ "multiplexer", required_argument, NULL, ARG_MULTIPLEXER },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{ "chain", no_argument, NULL, ARG_CHAIN },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -712,7 +769,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
for (;;) {
|
||||
int c;
|
||||
|
||||
c = getopt_long(argc, argv, "hjs:N", options, NULL);
|
||||
c = getopt_long(argc, argv,
|
||||
arg_chain ? "+hjs:N" : "hjs:N", /* When --chain was used disable parsing of further switches */
|
||||
options, NULL);
|
||||
if (c < 0)
|
||||
break;
|
||||
|
||||
@ -829,6 +888,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
SET_FLAG(arg_userdb_flags, USERDB_AVOID_MULTIPLEXER, !r);
|
||||
break;
|
||||
|
||||
case ARG_CHAIN:
|
||||
arg_chain = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -851,7 +914,7 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
/* This one is a helper for sshd_config's AuthorizedKeysCommand= setting, it's not a
|
||||
* user-facing verb and thus should not appear in man pages or --help texts. */
|
||||
{ "ssh-authorized-keys", 2, 2, 0, ssh_authorized_keys },
|
||||
{ "ssh-authorized-keys", 2, VERB_ANY, 0, ssh_authorized_keys },
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user