Brad Bishop | 1a4b7ee | 2018-12-16 17:11:34 -0800 | [diff] [blame] | 1 | From 86d18f3b09ec984ef3732567af992adb2dc77a8a Mon Sep 17 00:00:00 2001 |
| 2 | From: Yu Watanabe <watanabe.yu+github@gmail.com> |
| 3 | Date: Mon, 9 Jul 2018 14:05:20 +0900 |
| 4 | Subject: [PATCH] login: use parse_uid() when unmounting user runtime directory |
| 5 | |
| 6 | When unmounting user runtime directory, only UID is necessary, |
| 7 | and the corresponding user may not exist anymore. |
| 8 | This makes first try to parse the input by parse_uid(), and only if it |
| 9 | fails, prase the input by get_user_creds(). |
| 10 | |
| 11 | Fixes #9541. |
| 12 | |
| 13 | Upstream-Status: Backport |
| 14 | --- |
| 15 | src/login/user-runtime-dir.c | 57 ++++++++++++++++++++++++++++---------------- |
| 16 | 1 file changed, 36 insertions(+), 21 deletions(-) |
| 17 | |
| 18 | diff --git a/src/login/user-runtime-dir.c b/src/login/user-runtime-dir.c |
| 19 | index 1bb26c99e..de4061c75 100644 |
| 20 | --- a/src/login/user-runtime-dir.c |
| 21 | +++ b/src/login/user-runtime-dir.c |
| 22 | @@ -111,8 +111,22 @@ static int user_remove_runtime_path(const char *runtime_path) { |
| 23 | return r; |
| 24 | } |
| 25 | |
| 26 | -static int do_mount(const char *runtime_path, uid_t uid, gid_t gid) { |
| 27 | +static int do_mount(const char *user) { |
| 28 | + char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; |
| 29 | size_t runtime_dir_size; |
| 30 | + uid_t uid; |
| 31 | + gid_t gid; |
| 32 | + int r; |
| 33 | + |
| 34 | + r = get_user_creds(&user, &uid, &gid, NULL, NULL); |
| 35 | + if (r < 0) |
| 36 | + return log_error_errno(r, |
| 37 | + r == -ESRCH ? "No such user \"%s\"" : |
| 38 | + r == -ENOMSG ? "UID \"%s\" is invalid or has an invalid main group" |
| 39 | + : "Failed to look up user \"%s\": %m", |
| 40 | + user); |
| 41 | + |
| 42 | + xsprintf(runtime_path, "/run/user/" UID_FMT, uid); |
| 43 | |
| 44 | assert_se(gather_configuration(&runtime_dir_size) == 0); |
| 45 | |
| 46 | @@ -120,16 +134,30 @@ static int do_mount(const char *runtime_path, uid_t uid, gid_t gid) { |
| 47 | return user_mkdir_runtime_path(runtime_path, uid, gid, runtime_dir_size); |
| 48 | } |
| 49 | |
| 50 | -static int do_umount(const char *runtime_path) { |
| 51 | +static int do_umount(const char *user) { |
| 52 | + char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; |
| 53 | + uid_t uid; |
| 54 | + int r; |
| 55 | + |
| 56 | + /* The user may be already removed. So, first try to parse the string by parse_uid(), |
| 57 | + * and if it fails, fallback to get_user_creds().*/ |
| 58 | + if (parse_uid(user, &uid) < 0) { |
| 59 | + r = get_user_creds(&user, &uid, NULL, NULL, NULL); |
| 60 | + if (r < 0) |
| 61 | + return log_error_errno(r, |
| 62 | + r == -ESRCH ? "No such user \"%s\"" : |
| 63 | + r == -ENOMSG ? "UID \"%s\" is invalid or has an invalid main group" |
| 64 | + : "Failed to look up user \"%s\": %m", |
| 65 | + user); |
| 66 | + } |
| 67 | + |
| 68 | + xsprintf(runtime_path, "/run/user/" UID_FMT, uid); |
| 69 | + |
| 70 | log_debug("Will remove %s", runtime_path); |
| 71 | return user_remove_runtime_path(runtime_path); |
| 72 | } |
| 73 | |
| 74 | int main(int argc, char *argv[]) { |
| 75 | - const char *user; |
| 76 | - uid_t uid; |
| 77 | - gid_t gid; |
| 78 | - char runtime_path[sizeof("/run/user") + DECIMAL_STR_MAX(uid_t)]; |
| 79 | int r; |
| 80 | |
| 81 | log_parse_environment(); |
| 82 | @@ -146,23 +174,10 @@ int main(int argc, char *argv[]) { |
| 83 | |
| 84 | umask(0022); |
| 85 | |
| 86 | - user = argv[2]; |
| 87 | - r = get_user_creds(&user, &uid, &gid, NULL, NULL); |
| 88 | - if (r < 0) { |
| 89 | - log_error_errno(r, |
| 90 | - r == -ESRCH ? "No such user \"%s\"" : |
| 91 | - r == -ENOMSG ? "UID \"%s\" is invalid or has an invalid main group" |
| 92 | - : "Failed to look up user \"%s\": %m", |
| 93 | - user); |
| 94 | - return EXIT_FAILURE; |
| 95 | - } |
| 96 | - |
| 97 | - xsprintf(runtime_path, "/run/user/" UID_FMT, uid); |
| 98 | - |
| 99 | if (streq(argv[1], "start")) |
| 100 | - r = do_mount(runtime_path, uid, gid); |
| 101 | + r = do_mount(argv[2]); |
| 102 | else if (streq(argv[1], "stop")) |
| 103 | - r = do_umount(runtime_path); |
| 104 | + r = do_umount(argv[2]); |
| 105 | else |
| 106 | assert_not_reached("Unknown verb!"); |
| 107 | |
| 108 | -- |
| 109 | 2.11.0 |
| 110 | |