Compare commits
14 Commits
b596ef81b6
...
8ecedf1892
Author | SHA1 | Date |
---|---|---|
Zbigniew Jędrzejewski-Szmek | 8ecedf1892 | |
Lennart Poettering | f6793bbcf0 | |
Mike Yuan | f87863a8ff | |
Antonio Alvarez Feijoo | 58c3c2886d | |
Daan De Meyer | dbbe895807 | |
Zbigniew Jędrzejewski-Szmek | 8da8996181 | |
Zbigniew Jędrzejewski-Szmek | fb1ad8c2df | |
Zbigniew Jędrzejewski-Szmek | 7a5997bad1 | |
Zbigniew Jędrzejewski-Szmek | 64e225d4c3 | |
Zbigniew Jędrzejewski-Szmek | d9cb7338f9 | |
Zbigniew Jędrzejewski-Szmek | 654fa34796 | |
Zbigniew Jędrzejewski-Szmek | 0638a45ec9 | |
Zbigniew Jędrzejewski-Szmek | e97f1ad4c9 | |
Zbigniew Jędrzejewski-Szmek | 48e5aec4a3 |
|
@ -803,6 +803,10 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) {
|
|||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Refuse cgroup paths from outside our cgroup namespace */
|
||||
if (startswith(path, "/../"))
|
||||
return -EUNATCH;
|
||||
|
||||
/* Truncate suffix indicating the process is a zombie */
|
||||
e = endswith(path, " (deleted)");
|
||||
if (e)
|
||||
|
|
|
@ -102,8 +102,8 @@ int pid_get_comm(pid_t pid, char **ret) {
|
|||
_cleanup_free_ char *escaped = NULL, *comm = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
assert(pid >= 0);
|
||||
assert(ret);
|
||||
|
||||
if (pid == 0 || pid == getpid_cached()) {
|
||||
comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */
|
||||
|
@ -143,6 +143,9 @@ int pidref_get_comm(const PidRef *pid, char **ret) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
r = pid_get_comm(pid->pid, &comm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -289,6 +292,9 @@ int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlag
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -331,6 +337,9 @@ int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char *
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
r = pid_get_cmdline_strv(pid->pid, flags, &args);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -477,6 +486,9 @@ int pidref_is_kernel_thread(const PidRef *pid) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
result = pid_is_kernel_thread(pid->pid);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
@ -594,6 +606,9 @@ int pidref_get_uid(const PidRef *pid, uid_t *ret) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
r = pid_get_uid(pid->pid, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -794,6 +809,9 @@ int pidref_get_start_time(const PidRef *pid, usec_t *ret) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
r = pid_get_start_time(pid->pid, ret ? &t : NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1093,6 +1111,9 @@ int pidref_is_my_child(const PidRef *pid) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
result = pid_is_my_child(pid->pid);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
@ -1128,6 +1149,9 @@ int pidref_is_unwaited(const PidRef *pid) {
|
|||
if (!pidref_is_set(pid))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pid))
|
||||
return -EREMOTE;
|
||||
|
||||
if (pid->pid == 1 || pidref_is_self(pid))
|
||||
return true;
|
||||
|
||||
|
@ -1169,6 +1193,9 @@ int pidref_is_alive(const PidRef *pidref) {
|
|||
if (!pidref_is_set(pidref))
|
||||
return -ESRCH;
|
||||
|
||||
if (pidref_is_remote(pidref))
|
||||
return -EREMOTE;
|
||||
|
||||
result = pid_is_alive(pidref->pid);
|
||||
if (result < 0) {
|
||||
assert(result != -ESRCH);
|
||||
|
|
|
@ -193,7 +193,7 @@ int enroll_fido2(
|
|||
fflush(stdout);
|
||||
|
||||
fprintf(stderr,
|
||||
"\nPlease save this FIDO2 credential ID. It is required when unloocking the volume\n"
|
||||
"\nPlease save this FIDO2 credential ID. It is required when unlocking the volume\n"
|
||||
"using the associated FIDO2 keyslot which we just created. To configure automatic\n"
|
||||
"unlocking using this FIDO2 token, add an appropriate entry to your /etc/crypttab\n"
|
||||
"file, see %s for details.\n", link);
|
||||
|
|
|
@ -691,42 +691,7 @@ static void dump_home_record(UserRecord *hr) {
|
|||
}
|
||||
}
|
||||
|
||||
static int mangle_user_list(char **list, char ***ret) {
|
||||
char **l;
|
||||
|
||||
if (strv_isempty(list)) {
|
||||
_cleanup_free_ char *myself = NULL;
|
||||
|
||||
myself = getusername_malloc();
|
||||
if (!myself)
|
||||
return log_oom();
|
||||
|
||||
l = strv_new(myself);
|
||||
} else
|
||||
l = strv_copy(list);
|
||||
if (!l)
|
||||
return log_oom();
|
||||
|
||||
*ret = l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inspect_home(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_strv_free_ char **items = NULL;
|
||||
int r, ret = 0;
|
||||
|
||||
r = mangle_user_list(strv_skip(argv, 1), &items);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = acquire_bus(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
STRV_FOREACH(i, items) {
|
||||
static int inspect_home(sd_bus *bus, const char *name) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
|
@ -734,84 +699,70 @@ static int inspect_home(int argc, char *argv[], void *userdata) {
|
|||
const char *json;
|
||||
int incomplete;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
r = parse_uid(*i, &uid);
|
||||
r = parse_uid(name, &uid);
|
||||
if (r < 0) {
|
||||
if (!valid_user_group_name(*i, 0)) {
|
||||
log_error("Invalid user name '%s'.", *i);
|
||||
if (ret == 0)
|
||||
ret = -EINVAL;
|
||||
if (!valid_user_group_name(name, 0))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid user name '%s'.", name);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", *i);
|
||||
r = bus_call_method(bus, bus_mgr, "GetUserRecordByName", &error, &reply, "s", name);
|
||||
} else
|
||||
r = bus_call_method(bus, bus_mgr, "GetUserRecordByUID", &error, &reply, "u", (uint32_t) uid);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to inspect home: %s", bus_error_message(&error, r));
|
||||
|
||||
r = sd_bus_message_read(reply, "sbo", &json, &incomplete, NULL);
|
||||
if (r < 0) {
|
||||
bus_log_parse_error(r);
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse JSON identity: %m");
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse JSON identity: %m");
|
||||
|
||||
hr = user_record_new();
|
||||
if (!hr)
|
||||
return log_oom();
|
||||
|
||||
r = user_record_load(hr, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_LOG|USER_RECORD_PERMISSIVE);
|
||||
if (r < 0) {
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
|
||||
continue;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
hr->incomplete = incomplete;
|
||||
dump_home_record(hr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int authenticate_home(int argc, char *argv[], void *userdata) {
|
||||
static int inspect_homes(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_strv_free_ char **items = NULL;
|
||||
int r, ret = 0;
|
||||
|
||||
r = mangle_user_list(strv_skip(argv, 1), &items);
|
||||
if (r < 0)
|
||||
return r;
|
||||
int r;
|
||||
|
||||
r = acquire_bus(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
|
||||
pager_open(arg_pager_flags);
|
||||
|
||||
STRV_FOREACH(i, items) {
|
||||
char **args = strv_skip(argv, 1);
|
||||
if (args) {
|
||||
_cleanup_free_ char *myself = getusername_malloc();
|
||||
if (!myself)
|
||||
return log_oom();
|
||||
|
||||
return inspect_home(bus, myself);
|
||||
} else {
|
||||
STRV_FOREACH(arg, args)
|
||||
RET_GATHER(r, inspect_home(bus, *arg));
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
static int authenticate_home(sd_bus *bus, const char *name) {
|
||||
_cleanup_(user_record_unrefp) UserRecord *secret = NULL;
|
||||
int r;
|
||||
|
||||
r = acquire_passed_secrets(*i, &secret);
|
||||
r = acquire_passed_secrets(name, &secret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -823,7 +774,7 @@ static int authenticate_home(int argc, char *argv[], void *userdata) {
|
|||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append(m, "s", *i);
|
||||
r = sd_bus_message_append(m, "s", name);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
|
@ -833,19 +784,37 @@ static int authenticate_home(int argc, char *argv[], void *userdata) {
|
|||
|
||||
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
|
||||
if (r < 0) {
|
||||
r = handle_generic_user_record_error(*i, secret, &error, r, false);
|
||||
if (r < 0) {
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
|
||||
break;
|
||||
r = handle_generic_user_record_error(name, secret, &error, r, false);
|
||||
if (r >= 0)
|
||||
continue;
|
||||
}
|
||||
} else
|
||||
break;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
static int authenticate_homes(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
int r;
|
||||
|
||||
r = acquire_bus(&bus);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) polkit_agent_open_if_enabled(arg_transport, arg_ask_password);
|
||||
|
||||
char **args = strv_skip(argv, 1);
|
||||
if (args) {
|
||||
_cleanup_free_ char *myself = getusername_malloc();
|
||||
if (!myself)
|
||||
return log_oom();
|
||||
|
||||
return authenticate_home(bus, myself);
|
||||
} else {
|
||||
STRV_FOREACH(arg, args)
|
||||
RET_GATHER(r, authenticate_home(bus, *arg));
|
||||
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
static int update_last_change(sd_json_variant **v, bool with_password, bool override) {
|
||||
|
@ -4721,8 +4690,8 @@ static int run(int argc, char *argv[]) {
|
|||
{ "list", VERB_ANY, 1, VERB_DEFAULT, list_homes },
|
||||
{ "activate", 2, VERB_ANY, 0, activate_home },
|
||||
{ "deactivate", 2, VERB_ANY, 0, deactivate_home },
|
||||
{ "inspect", VERB_ANY, VERB_ANY, 0, inspect_home },
|
||||
{ "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_home },
|
||||
{ "inspect", VERB_ANY, VERB_ANY, 0, inspect_homes },
|
||||
{ "authenticate", VERB_ANY, VERB_ANY, 0, authenticate_homes },
|
||||
{ "create", VERB_ANY, 2, 0, create_home },
|
||||
{ "remove", 2, VERB_ANY, 0, remove_home },
|
||||
{ "update", VERB_ANY, 2, 0, update_home },
|
||||
|
|
|
@ -46,13 +46,17 @@ static bool argv_has_at(pid_t pid) {
|
|||
return c == '@';
|
||||
}
|
||||
|
||||
static bool is_survivor_cgroup(const PidRef *pid) {
|
||||
static bool is_in_survivor_cgroup(const PidRef *pid) {
|
||||
_cleanup_free_ char *cgroup_path = NULL;
|
||||
int r;
|
||||
|
||||
assert(pidref_is_set(pid));
|
||||
|
||||
r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path);
|
||||
if (r == -EUNATCH) {
|
||||
log_warning_errno(r, "Process " PID_FMT " appears to originate in foreign namespace, ignoring.", pid->pid);
|
||||
return true;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid);
|
||||
return false;
|
||||
|
@ -86,7 +90,7 @@ static bool ignore_proc(const PidRef *pid, bool warn_rootfs) {
|
|||
return true; /* also ignore processes where we can't determine this */
|
||||
|
||||
/* Ignore processes that are part of a cgroup marked with the user.survive_final_kill_signal xattr */
|
||||
if (is_survivor_cgroup(pid))
|
||||
if (is_in_survivor_cgroup(pid))
|
||||
return true;
|
||||
|
||||
r = pidref_get_uid(pid, &uid);
|
||||
|
|
|
@ -7,24 +7,26 @@ TEST(audit_loginuid_from_pid) {
|
|||
_cleanup_(pidref_done) PidRef self = PIDREF_NULL, pid1 = PIDREF_NULL;
|
||||
int r;
|
||||
|
||||
assert_se(pidref_set_self(&self) >= 0);
|
||||
assert_se(pidref_set_pid(&pid1, 1) >= 0);
|
||||
ASSERT_OK(pidref_set_self(&self));
|
||||
ASSERT_OK(pidref_set_pid(&pid1, 1));
|
||||
|
||||
uid_t uid;
|
||||
r = audit_loginuid_from_pid(&self, &uid);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
if (r != -ENODATA)
|
||||
ASSERT_OK(r);
|
||||
if (r >= 0)
|
||||
log_info("self audit login uid: " UID_FMT, uid);
|
||||
|
||||
assert_se(audit_loginuid_from_pid(&pid1, &uid) == -ENODATA);
|
||||
ASSERT_ERROR(audit_loginuid_from_pid(&pid1, &uid), ENODATA);
|
||||
|
||||
uint32_t sessionid;
|
||||
r = audit_session_from_pid(&self, &sessionid);
|
||||
assert_se(r >= 0 || r == -ENODATA);
|
||||
if (r != -ENODATA)
|
||||
ASSERT_OK(r);
|
||||
if (r >= 0)
|
||||
log_info("self audit session id: %" PRIu32, sessionid);
|
||||
|
||||
assert_se(audit_session_from_pid(&pid1, &sessionid) == -ENODATA);
|
||||
ASSERT_ERROR(audit_session_from_pid(&pid1, &sessionid), ENODATA);
|
||||
}
|
||||
|
||||
static int intro(void) {
|
||||
|
|
Loading…
Reference in New Issue