mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #1568 from poettering/netclass
various fixes, for various things
This commit is contained in:
@@ -411,6 +411,23 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>NetClass=</varname></term>
|
||||
<listitem><para>Configures a network class number to assign to the
|
||||
unit. This value will be set to the
|
||||
<literal>net_cls.class_id</literal> property of the
|
||||
<literal>net_cls</literal> cgroup of the unit. The directive
|
||||
accepts a numerical value (for fixed number assignment) and the keyword
|
||||
<literal>auto</literal> (for dynamic allocation). Network traffic of
|
||||
all processes inside the unit will have the network class ID assigned
|
||||
by the kernel. Also see
|
||||
the kernel docs for
|
||||
<ulink url="https://www.kernel.org/doc/Documentation/cgroups/net_cls.txt">net_cls controller</ulink>
|
||||
and
|
||||
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Slice=</varname></term>
|
||||
|
||||
|
||||
@@ -1045,22 +1045,6 @@
|
||||
units.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>NetClass=</varname></term>
|
||||
<listitem><para>Configures a network class number to assign to the
|
||||
unit. This value will be set to the
|
||||
<literal>net_cls.class_id</literal> property of the
|
||||
<literal>net_cls</literal> cgroup of the unit. The directive
|
||||
accepts a numerical value (for fixed number assignment) and the keyword
|
||||
<literal>auto</literal> (for dynamic allocation). Network traffic of
|
||||
all processes inside the unit will have the network class ID assigned
|
||||
by the kernel. Also see
|
||||
the kernel docs for
|
||||
<ulink url="https://www.kernel.org/doc/Documentation/cgroups/net_cls.txt">net_cls controller</ulink>
|
||||
and
|
||||
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect1>
|
||||
|
||||
@@ -144,7 +144,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_strv_free_erase_ char **l = NULL;
|
||||
usec_t timeout;
|
||||
char **p;
|
||||
int r;
|
||||
|
||||
@@ -86,6 +86,15 @@ char **strv_free(char **l) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char **strv_free_erase(char **l) {
|
||||
char **i;
|
||||
|
||||
STRV_FOREACH(i, l)
|
||||
string_erase(*i);
|
||||
|
||||
return strv_free(l);
|
||||
}
|
||||
|
||||
char **strv_copy(char * const *l) {
|
||||
char **r, **k;
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@ char **strv_free(char **l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
|
||||
#define _cleanup_strv_free_ _cleanup_(strv_freep)
|
||||
|
||||
char **strv_free_erase(char **l);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
|
||||
#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
|
||||
|
||||
void strv_clear(char **l);
|
||||
|
||||
char **strv_copy(char * const *l);
|
||||
|
||||
@@ -6805,3 +6805,22 @@ bool fdname_is_valid(const char *s) {
|
||||
bool oom_score_adjust_is_valid(int oa) {
|
||||
return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
|
||||
}
|
||||
|
||||
void string_erase(char *x) {
|
||||
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
/* A delicious drop of snake-oil! To be called on memory where
|
||||
* we stored passphrases or so, after we used them. */
|
||||
|
||||
memory_erase(x, strlen(x));
|
||||
}
|
||||
|
||||
char *string_free_erase(char *s) {
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
string_erase(s);
|
||||
return mfree(s);
|
||||
}
|
||||
|
||||
@@ -943,3 +943,10 @@ int version(void);
|
||||
bool fdname_is_valid(const char *s);
|
||||
|
||||
bool oom_score_adjust_is_valid(int oa);
|
||||
|
||||
#define memory_erase(p, l) memset((p), 'x', (l))
|
||||
void string_erase(char *x);
|
||||
|
||||
char *string_free_erase(char *s);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
|
||||
#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
|
||||
|
||||
@@ -1208,8 +1208,9 @@ int bus_exec_context_set_transient_property(
|
||||
|
||||
_cleanup_free_ char *joined = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char **l = NULL;
|
||||
size_t size = 0;
|
||||
bool empty_array = true;
|
||||
char **i;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "(sb)");
|
||||
if (r < 0)
|
||||
@@ -1219,18 +1220,13 @@ int bus_exec_context_set_transient_property(
|
||||
if (!f)
|
||||
return -ENOMEM;
|
||||
|
||||
if (mode != UNIT_CHECK) {
|
||||
char **buf;
|
||||
STRV_FOREACH(buf, c->environment_files)
|
||||
fprintf(f, "EnvironmentFile=%s\n", *buf);
|
||||
}
|
||||
STRV_FOREACH(i, c->environment_files)
|
||||
fprintf(f, "EnvironmentFile=%s\n", *i);
|
||||
|
||||
while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
|
||||
const char *path;
|
||||
int b;
|
||||
|
||||
empty_array = false;
|
||||
|
||||
r = sd_bus_message_read(message, "sb", &path, &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1247,12 +1243,12 @@ int bus_exec_context_set_transient_property(
|
||||
char *buf = NULL;
|
||||
|
||||
buf = strjoin(b ? "-" : "", path, NULL);
|
||||
if (buf == NULL)
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
fprintf(f, "EnvironmentFile=%s\n", buf);
|
||||
|
||||
r = strv_consume(&c->environment_files, buf);
|
||||
r = strv_consume(&l, buf);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -1260,14 +1256,22 @@ int bus_exec_context_set_transient_property(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
fflush(f);
|
||||
r = fflush_and_check(f);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (mode != UNIT_CHECK)
|
||||
if (empty_array) {
|
||||
strv_clear(c->environment_files);
|
||||
if (mode != UNIT_CHECK) {
|
||||
if (strv_isempty(l)) {
|
||||
c->environment_files = strv_free(c->environment_files);
|
||||
unit_write_drop_in_private(u, mode, name, "EnvironmentFile=\n");
|
||||
} else
|
||||
} else {
|
||||
r = strv_extend_strv(&c->environment_files, l, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_drop_in_private(u, mode, name, joined);
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
|
||||
@@ -679,7 +679,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
||||
SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), 0),
|
||||
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("NetClass", "u", bus_property_get_unsigned, offsetof(Unit, cgroup_netclass_id), 0),
|
||||
SD_BUS_PROPERTY("NetClass", "u", NULL, offsetof(Unit, cgroup_netclass_id), 0),
|
||||
|
||||
SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||
|
||||
@@ -2742,6 +2742,7 @@ int config_parse_tasks_max(
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->tasks_max = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2952,9 +2952,9 @@ void manager_set_show_status(Manager *m, ShowStatus mode) {
|
||||
m->show_status = mode;
|
||||
|
||||
if (mode > 0)
|
||||
touch("/run/systemd/show-status");
|
||||
(void) touch("/run/systemd/show-status");
|
||||
else
|
||||
unlink("/run/systemd/show-status");
|
||||
(void) unlink("/run/systemd/show-status");
|
||||
}
|
||||
|
||||
static bool manager_get_show_status(Manager *m, StatusType type) {
|
||||
|
||||
@@ -1215,7 +1215,7 @@ static int service_spawn(
|
||||
|
||||
if (is_control && UNIT(s)->cgroup_path) {
|
||||
path = strjoina(UNIT(s)->cgroup_path, "/control");
|
||||
cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
|
||||
(void) cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
|
||||
} else
|
||||
path = UNIT(s)->cgroup_path;
|
||||
|
||||
|
||||
@@ -312,15 +312,16 @@ static char *disk_mount_point(const char *label) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) {
|
||||
static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***ret) {
|
||||
_cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *maj_min = NULL, *text = NULL, *escaped_name = NULL;
|
||||
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||
const char *name = NULL;
|
||||
char **p, *id;
|
||||
int r = 0;
|
||||
|
||||
assert(vol);
|
||||
assert(src);
|
||||
assert(passwords);
|
||||
assert(ret);
|
||||
|
||||
description = disk_description(src);
|
||||
mount_point = disk_mount_point(vol);
|
||||
@@ -360,14 +361,16 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
|
||||
|
||||
id = strjoina("cryptsetup:", escaped_name);
|
||||
|
||||
r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE|(accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0), passwords);
|
||||
r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until,
|
||||
ASK_PASSWORD_PUSH_CACHE | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
|
||||
&passwords);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query password: %m");
|
||||
|
||||
if (arg_verify) {
|
||||
_cleanup_strv_free_ char **passwords2 = NULL;
|
||||
_cleanup_strv_free_erase_ char **passwords2 = NULL;
|
||||
|
||||
assert(strv_length(*passwords) == 1);
|
||||
assert(strv_length(passwords) == 1);
|
||||
|
||||
if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0)
|
||||
return log_oom();
|
||||
@@ -380,22 +383,23 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
|
||||
|
||||
assert(strv_length(passwords2) == 1);
|
||||
|
||||
if (!streq(*passwords[0], passwords2[0])) {
|
||||
if (!streq(passwords[0], passwords2[0])) {
|
||||
log_warning("Passwords did not match, retrying.");
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
|
||||
strv_uniq(*passwords);
|
||||
strv_uniq(passwords);
|
||||
|
||||
STRV_FOREACH(p, *passwords) {
|
||||
STRV_FOREACH(p, passwords) {
|
||||
char *c;
|
||||
|
||||
if (strlen(*p)+1 >= arg_key_size)
|
||||
continue;
|
||||
|
||||
/* Pad password if necessary */
|
||||
if (!(c = new(char, arg_key_size)))
|
||||
c = new(char, arg_key_size);
|
||||
if (!c)
|
||||
return log_oom();
|
||||
|
||||
strncpy(c, *p, arg_key_size);
|
||||
@@ -403,14 +407,19 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
|
||||
*p = c;
|
||||
}
|
||||
|
||||
*ret = passwords;
|
||||
passwords = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int attach_tcrypt(struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *key_file,
|
||||
char **passwords,
|
||||
uint32_t flags) {
|
||||
static int attach_tcrypt(
|
||||
struct crypt_device *cd,
|
||||
const char *name,
|
||||
const char *key_file,
|
||||
char **passwords,
|
||||
uint32_t flags) {
|
||||
|
||||
int r = 0;
|
||||
_cleanup_free_ char *passphrase = NULL;
|
||||
struct crypt_params_tcrypt params = {
|
||||
@@ -520,8 +529,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
|
||||
* it just configures encryption
|
||||
* parameters when used for plain
|
||||
* mode. */
|
||||
r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode,
|
||||
NULL, NULL, arg_keyfile_size, ¶ms);
|
||||
r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, ¶ms);
|
||||
|
||||
/* hash == NULL implies the user passed "plain" */
|
||||
pass_volume_key = (params.hash == NULL);
|
||||
@@ -537,9 +545,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
|
||||
crypt_get_device_name(cd));
|
||||
|
||||
if (key_file) {
|
||||
r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot,
|
||||
key_file, arg_keyfile_size,
|
||||
arg_keyfile_offset, flags);
|
||||
r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
|
||||
return -EAGAIN;
|
||||
@@ -631,7 +637,6 @@ int main(int argc, char *argv[]) {
|
||||
k = crypt_init(&cd, arg_header);
|
||||
} else
|
||||
k = crypt_init(&cd, argv[3]);
|
||||
|
||||
if (k) {
|
||||
log_error_errno(k, "crypt_init() failed: %m");
|
||||
goto finish;
|
||||
@@ -669,7 +674,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
|
||||
_cleanup_strv_free_ char **passwords = NULL;
|
||||
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||
|
||||
if (!key_file) {
|
||||
k = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords);
|
||||
|
||||
@@ -51,15 +51,6 @@ static bool arg_copy_locale = false;
|
||||
static bool arg_copy_timezone = false;
|
||||
static bool arg_copy_root_password = false;
|
||||
|
||||
static void clear_string(char *x) {
|
||||
|
||||
if (!x)
|
||||
return;
|
||||
|
||||
/* A delicious drop of snake-oil! */
|
||||
memset(x, 'x', strlen(x));
|
||||
}
|
||||
|
||||
static bool press_any_key(void) {
|
||||
char k = 0;
|
||||
bool need_nl = true;
|
||||
@@ -464,7 +455,7 @@ static int prompt_root_password(void) {
|
||||
msg2 = strjoina(draw_special_char(DRAW_TRIANGULAR_BULLET), " Please enter new root password again: ");
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *a = NULL, *b = NULL;
|
||||
_cleanup_string_free_erase_ char *a = NULL, *b = NULL;
|
||||
|
||||
r = ask_password_tty(msg1, NULL, 0, 0, NULL, &a);
|
||||
if (r < 0)
|
||||
@@ -476,19 +467,14 @@ static int prompt_root_password(void) {
|
||||
}
|
||||
|
||||
r = ask_password_tty(msg2, NULL, 0, 0, NULL, &b);
|
||||
if (r < 0) {
|
||||
clear_string(a);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query root password: %m");
|
||||
}
|
||||
|
||||
if (!streq(a, b)) {
|
||||
log_error("Entered passwords did not match, please try again.");
|
||||
clear_string(a);
|
||||
clear_string(b);
|
||||
continue;
|
||||
}
|
||||
|
||||
clear_string(b);
|
||||
arg_root_password = a;
|
||||
a = NULL;
|
||||
break;
|
||||
@@ -881,7 +867,7 @@ finish:
|
||||
free(arg_locale_messages);
|
||||
free(arg_timezone);
|
||||
free(arg_hostname);
|
||||
clear_string(arg_root_password);
|
||||
string_erase(arg_root_password);
|
||||
free(arg_root_password);
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
|
||||
@@ -217,13 +217,11 @@ int journal_directory_vacuum(
|
||||
|
||||
de->d_name[q-8-16-1-16-1] = 0;
|
||||
if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) {
|
||||
free(p);
|
||||
n_active_files++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) {
|
||||
free(p);
|
||||
n_active_files++;
|
||||
continue;
|
||||
}
|
||||
@@ -253,7 +251,6 @@ int journal_directory_vacuum(
|
||||
}
|
||||
|
||||
if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) {
|
||||
free(p);
|
||||
n_active_files ++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -930,7 +930,7 @@ finish:
|
||||
|
||||
static int system_journal_open(Server *s, bool flush_requested) {
|
||||
const char *fn;
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
if (!s->system_journal &&
|
||||
(s->storage == STORAGE_PERSISTENT || s->storage == STORAGE_AUTO) &&
|
||||
@@ -1231,7 +1231,7 @@ static int dispatch_sigusr1(sd_event_source *es, const struct signalfd_siginfo *
|
||||
server_sync(s);
|
||||
server_vacuum(s, false, false);
|
||||
|
||||
touch("/run/systemd/journal/flushed");
|
||||
(void) touch("/run/systemd/journal/flushed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -50,9 +50,10 @@ static int send_on_socket(int fd, const char *socket_name, const void *packet, s
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd = -1, r = EXIT_FAILURE;
|
||||
_cleanup_close_ int fd = -1;
|
||||
char packet[LINE_MAX];
|
||||
size_t length;
|
||||
int r;
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_parse_environment();
|
||||
@@ -60,14 +61,14 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (argc != 3) {
|
||||
log_error("Wrong number of arguments.");
|
||||
goto finish;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (streq(argv[1], "1")) {
|
||||
|
||||
packet[0] = '+';
|
||||
if (!fgets(packet+1, sizeof(packet)-1, stdin)) {
|
||||
log_error_errno(errno, "Failed to read password: %m");
|
||||
r = log_error_errno(errno, "Failed to read password: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -78,22 +79,20 @@ int main(int argc, char *argv[]) {
|
||||
length = 1;
|
||||
} else {
|
||||
log_error("Invalid first argument %s", argv[1]);
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (fd < 0) {
|
||||
log_error_errno(errno, "socket() failed: %m");
|
||||
r = log_error_errno(errno, "socket() failed: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (send_on_socket(fd, argv[2], packet, length) < 0)
|
||||
goto finish;
|
||||
|
||||
r = EXIT_SUCCESS;
|
||||
r = send_on_socket(fd, argv[2], packet, length);
|
||||
|
||||
finish:
|
||||
safe_close(fd);
|
||||
memory_erase(packet, sizeof(packet));
|
||||
|
||||
return r;
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
|
||||
if (n < m)
|
||||
break;
|
||||
|
||||
memory_erase(p, n);
|
||||
free(p);
|
||||
m *= 2;
|
||||
}
|
||||
@@ -86,12 +87,14 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
memory_erase(p, n);
|
||||
|
||||
*ret = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **passwords) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
_cleanup_strv_free_erase_ char **l = NULL;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
key_serial_t serial;
|
||||
size_t n;
|
||||
@@ -124,6 +127,7 @@ static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **pa
|
||||
assert(p[n-1] == 0);
|
||||
|
||||
serial = add_key("user", keyname, p, n-1, KEY_SPEC_USER_KEYRING);
|
||||
memory_erase(p, n);
|
||||
if (serial == -1)
|
||||
return -errno;
|
||||
|
||||
@@ -361,9 +365,12 @@ int ask_password_tty(
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
c = 'x';
|
||||
}
|
||||
|
||||
x = strndup(passphrase, p);
|
||||
memory_erase(passphrase, p);
|
||||
if (!x) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
@@ -620,6 +627,7 @@ int ask_password_agent(
|
||||
l = strv_new("", NULL);
|
||||
else
|
||||
l = strv_parse_nulstr(passphrase+1, n-1);
|
||||
memory_erase(passphrase, n);
|
||||
if (!l) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
@@ -688,9 +696,12 @@ int ask_password_auto(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = strv_consume(&l, s);
|
||||
if (r < 0)
|
||||
r = strv_push(&l, s);
|
||||
if (r < 0) {
|
||||
string_erase(s);
|
||||
free(s);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*ret = l;
|
||||
return 0;
|
||||
|
||||
@@ -57,12 +57,12 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||
|
||||
/* Try to fix the access mode, so that we can still
|
||||
touch the file after dropping priviliges */
|
||||
fchmod(fd, 0644);
|
||||
fchown(fd, uid, gid);
|
||||
(void) fchmod(fd, 0644);
|
||||
(void) fchown(fd, uid, gid);
|
||||
|
||||
} else
|
||||
/* create stamp file with the compiled-in date */
|
||||
touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644);
|
||||
(void) touch_file("/var/lib/systemd/clock", true, min, uid, gid, 0644);
|
||||
|
||||
ct = now(CLOCK_REALTIME);
|
||||
if (ct < min) {
|
||||
@@ -150,7 +150,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
/* if we got an authoritative time, store it in the file system */
|
||||
if (m->sync)
|
||||
touch("/var/lib/systemd/clock");
|
||||
(void) touch("/var/lib/systemd/clock");
|
||||
|
||||
sd_event_get_exit_code(m->event, &r);
|
||||
|
||||
|
||||
@@ -120,23 +120,30 @@ static int ask_password_plymouth(
|
||||
|
||||
y = now(CLOCK_MONOTONIC);
|
||||
|
||||
if (y > until)
|
||||
return -ETIME;
|
||||
if (y > until) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sleep_for = (int) ((until - y) / USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
if (flag_file && access(flag_file, F_OK) < 0)
|
||||
return -errno;
|
||||
if (flag_file && access(flag_file, F_OK) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
j = poll(pollfd, notify >= 0 ? 2 : 1, sleep_for);
|
||||
if (j < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
} else if (j == 0)
|
||||
return -ETIME;
|
||||
r = -errno;
|
||||
goto finish;
|
||||
} else if (j == 0) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
flush_fd(notify);
|
||||
@@ -149,9 +156,12 @@ static int ask_password_plymouth(
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
|
||||
return -errno;
|
||||
} else if (k == 0)
|
||||
return -EIO;
|
||||
r = -errno;
|
||||
goto finish;
|
||||
} else if (k == 0) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
p += k;
|
||||
|
||||
@@ -166,12 +176,14 @@ static int ask_password_plymouth(
|
||||
* with a normal password request */
|
||||
packet = mfree(packet);
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
|
||||
return -ENOMEM;
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = loop_write(fd, packet, n+1, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
goto finish;
|
||||
|
||||
flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||
p = 0;
|
||||
@@ -179,7 +191,8 @@ static int ask_password_plymouth(
|
||||
}
|
||||
|
||||
/* No password, because UI not shown */
|
||||
return -ENOENT;
|
||||
r = -ENOENT;
|
||||
goto finish;
|
||||
|
||||
} else if (buffer[0] == 2 || buffer[0] == 9) {
|
||||
uint32_t size;
|
||||
@@ -191,32 +204,43 @@ static int ask_password_plymouth(
|
||||
|
||||
memcpy(&size, buffer+1, sizeof(size));
|
||||
size = le32toh(size);
|
||||
if (size + 5 > sizeof(buffer))
|
||||
return -EIO;
|
||||
if (size + 5 > sizeof(buffer)) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (p-5 < size)
|
||||
continue;
|
||||
|
||||
l = strv_parse_nulstr(buffer + 5, size);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
if (!l) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
*ret = l;
|
||||
break;
|
||||
|
||||
} else
|
||||
} else {
|
||||
/* Unknown packet */
|
||||
return -EIO;
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
memory_erase(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int parse_password(const char *filename, char **wall) {
|
||||
_cleanup_free_ char *socket_name = NULL, *message = NULL, *packet = NULL;
|
||||
bool accept_cached = false, echo = false;
|
||||
size_t packet_length = 0;
|
||||
uint64_t not_after = 0;
|
||||
unsigned pid = 0;
|
||||
bool accept_cached = false, echo = false;
|
||||
|
||||
const ConfigTableItem items[] = {
|
||||
{ "Ask", "Socket", config_parse_string, 0, &socket_name },
|
||||
@@ -270,7 +294,6 @@ static int parse_password(const char *filename, char **wall) {
|
||||
|
||||
} else {
|
||||
union sockaddr_union sa = {};
|
||||
size_t packet_length = 0;
|
||||
_cleanup_close_ int socket_fd = -1;
|
||||
|
||||
assert(arg_action == ACTION_QUERY ||
|
||||
@@ -284,7 +307,7 @@ static int parse_password(const char *filename, char **wall) {
|
||||
}
|
||||
|
||||
if (arg_plymouth) {
|
||||
_cleanup_strv_free_ char **passwords = NULL;
|
||||
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||
|
||||
r = ask_password_plymouth(message, not_after, accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0, filename, &passwords);
|
||||
if (r >= 0) {
|
||||
@@ -308,7 +331,7 @@ static int parse_password(const char *filename, char **wall) {
|
||||
}
|
||||
|
||||
} else {
|
||||
_cleanup_free_ char *password = NULL;
|
||||
_cleanup_string_free_erase_ char *password = NULL;
|
||||
int tty_fd = -1;
|
||||
|
||||
if (arg_console) {
|
||||
@@ -340,26 +363,36 @@ static int parse_password(const char *filename, char **wall) {
|
||||
}
|
||||
}
|
||||
|
||||
if (IN_SET(r, -ETIME, -ENOENT))
|
||||
if (IN_SET(r, -ETIME, -ENOENT)) {
|
||||
/* If the query went away, that's OK */
|
||||
return 0;
|
||||
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query password: %m");
|
||||
r = 0;
|
||||
goto finish;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to query password: %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
|
||||
if (socket_fd < 0)
|
||||
return log_error_errno(errno, "socket(): %m");
|
||||
if (socket_fd < 0) {
|
||||
r = log_error_errno(errno, "socket(): %m");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sa.un.sun_family = AF_UNIX;
|
||||
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
|
||||
|
||||
r = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name));
|
||||
memory_erase(packet, packet_length);
|
||||
if (r < 0)
|
||||
return log_error_errno(errno, "Failed to send: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
finish:
|
||||
memory_erase(packet, packet_length);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int wall_tty_block(void) {
|
||||
|
||||
Reference in New Issue
Block a user