diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/unit-printf.c | 168 | ||||
-rw-r--r-- | src/shared/install-printf.c | 52 | ||||
-rw-r--r-- | src/shared/install.c | 31 | ||||
-rw-r--r-- | src/shared/install.h | 1 | ||||
-rw-r--r-- | src/test/test-unit-file.c | 51 | ||||
-rw-r--r-- | src/test/test-unit-name.c | 27 |
6 files changed, 78 insertions, 252 deletions
diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 721c8ccce9..f587a5a141 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -159,162 +159,43 @@ static int specifier_runtime(char specifier, void *data, void *userdata, char ** } static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) { - char *printed = NULL; - Unit *u = userdata; - ExecContext *c; - int r = 0; - - assert(u); - - c = unit_get_exec_context(u); - if (!c) - return -EOPNOTSUPP; - - if (u->manager->running_as == MANAGER_SYSTEM) { - - /* We cannot use NSS from PID 1, hence try to make the - * best of it in that case, and fail if we can't help - * it */ - - if (!c->user || streq(c->user, "root") || streq(c->user, "0")) - printed = strdup(specifier == 'u' ? "root" : "0"); - else { - if (specifier == 'u') - printed = strdup(c->user); - else { - uid_t uid; + char *t; - r = parse_uid(c->user, &uid); - if (r < 0) - return -ENODATA; - - r = asprintf(&printed, UID_FMT, uid); - } - } - - } else { - _cleanup_free_ char *tmp = NULL; - const char *username = NULL; - uid_t uid; - - if (c->user) - username = c->user; - else - /* get USER env from env or our own uid */ - username = tmp = getusername_malloc(); - - /* fish username from passwd */ - r = get_user_creds(&username, &uid, NULL, NULL, NULL); - if (r < 0) - return r; - - if (specifier == 'u') - printed = strdup(username); - else - r = asprintf(&printed, UID_FMT, uid); - } + /* If we are UID 0 (root), this will not result in NSS, + * otherwise it might. This is good, as we want to be able to + * run this in PID 1, where our user ID is 0, but where NSS + * lookups are not allowed. */ - if (r < 0 || !printed) + t = getusername_malloc(); + if (!t) return -ENOMEM; - *ret = printed; + *ret = t; return 0; } -static int specifier_user_home(char specifier, void *data, void *userdata, char **ret) { - Unit *u = userdata; - ExecContext *c; - char *n; - int r; - - assert(u); - - c = unit_get_exec_context(u); - if (!c) - return -EOPNOTSUPP; - - if (u->manager->running_as == MANAGER_SYSTEM) { - - /* We cannot use NSS from PID 1, hence try to make the - * best of it if we can, but fail if we can't */ - - if (!c->user || streq(c->user, "root") || streq(c->user, "0")) - n = strdup("/root"); - else - return -EOPNOTSUPP; - - } else { +static int specifier_user_id(char specifier, void *data, void *userdata, char **ret) { - /* return HOME if set, otherwise from passwd */ - if (!c || !c->user) { - r = get_home_dir(&n); - if (r < 0) - return r; - } else { - const char *username, *home; - - username = c->user; - r = get_user_creds(&username, NULL, NULL, &home, NULL); - if (r < 0) - return r; - - n = strdup(home); - } - } - - if (!n) + if (asprintf(ret, UID_FMT, getuid()) < 0) return -ENOMEM; - *ret = n; return 0; } -static int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) { - Unit *u = userdata; - ExecContext *c; - char *n; - int r; - - assert(u); - - c = unit_get_exec_context(u); - if (!c) - return -EOPNOTSUPP; - - if (u->manager->running_as == MANAGER_SYSTEM) { - - /* We cannot use NSS from PID 1, hence try to make the - * best of it if we can, but fail if we can't */ - - if (!c->user || streq(c->user, "root") || streq(c->user, "0")) - n = strdup("/bin/sh"); - else - return -EOPNOTSUPP; - - } else { +static int specifier_user_home(char specifier, void *data, void *userdata, char **ret) { - /* return /bin/sh for root, otherwise the value from passwd */ - if (!c->user) { - r = get_shell(&n); - if (r < 0) - return r; - } else { - const char *username, *shell; + /* On PID 1 (which runs as root) this will not result in NSS, + * which is good. See above */ - username = c->user; - r = get_user_creds(&username, NULL, NULL, NULL, &shell); - if (r < 0) - return r; + return get_home_dir(ret); +} - n = strdup(shell); - } - } +static int specifier_user_shell(char specifier, void *data, void *userdata, char **ret) { - if (!n) - return -ENOMEM; + /* On PID 1 (which runs as root) this will not result in NSS, + * which is good. See above */ - *ret = n; - return 0; + return get_shell(ret); } int unit_name_printf(Unit *u, const char* format, char **ret) { @@ -354,10 +235,10 @@ int unit_full_printf(Unit *u, const char *format, char **ret) { * %r where units in this slice are placed in the cgroup tree * %R the root of this systemd's instance tree * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR) - * %U the UID of the configured user or running user - * %u the username of the configured user or running user - * %h the homedir of the configured user or running user - * %s the shell of the configured user or running user + * %U the UID of the running user + * %u the username of the running user + * %h the homedir of the running user + * %s the shell of the running user * %m the machine ID of the running system * %H the host name of the running system * %b the boot ID of the running system @@ -377,7 +258,8 @@ int unit_full_printf(Unit *u, const char *format, char **ret) { { 'r', specifier_cgroup_slice, NULL }, { 'R', specifier_cgroup_root, NULL }, { 't', specifier_runtime, NULL }, - { 'U', specifier_user_name, NULL }, + + { 'U', specifier_user_id, NULL }, { 'u', specifier_user_name, NULL }, { 'h', specifier_user_home, NULL }, { 's', specifier_user_shell, NULL }, diff --git a/src/shared/install-printf.c b/src/shared/install-printf.c index e1cb5d27ff..74b909d34d 100644 --- a/src/shared/install-printf.c +++ b/src/shared/install-printf.c @@ -67,42 +67,28 @@ static int specifier_instance(char specifier, void *data, void *userdata, char * } static int specifier_user_name(char specifier, void *data, void *userdata, char **ret) { - UnitFileInstallInfo *i = userdata; - const char *username; - _cleanup_free_ char *tmp = NULL; - char *printed = NULL; - - assert(i); + char *t; - if (i->user) - username = i->user; - else - /* get USER env from env or our own uid */ - username = tmp = getusername_malloc(); - - switch (specifier) { - case 'u': - printed = strdup(username); - break; - case 'U': { - /* fish username from passwd */ - uid_t uid; - int r; - - r = get_user_creds(&username, &uid, NULL, NULL, NULL); - if (r < 0) - return r; - - if (asprintf(&printed, UID_FMT, uid) < 0) - return -ENOMEM; - break; - }} + /* If we are UID 0 (root), this will not result in NSS, + * otherwise it might. This is good, as we want to be able to + * run this in PID 1, where our user ID is 0, but where NSS + * lookups are not allowed. */ + t = getusername_malloc(); + if (!t) + return -ENOMEM; - *ret = printed; + *ret = t; return 0; } +static int specifier_user_id(char specifier, void *data, void *userdata, char **ret) { + + if (asprintf(ret, UID_FMT, getuid()) < 0) + return -ENOMEM; + + return 0; +} int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) { @@ -114,8 +100,8 @@ int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) * %p: the prefix (foo) * %i: the instance (bar) - * %U the UID of the configured user or running user - * %u the username of the configured user or running user + * %U the UID of the running user + * %u the username of running user * %m the machine ID of the running system * %H the host name of the running system * %b the boot ID of the running system @@ -128,7 +114,7 @@ int install_full_printf(UnitFileInstallInfo *i, const char *format, char **ret) { 'p', specifier_prefix, NULL }, { 'i', specifier_instance, NULL }, - { 'U', specifier_user_name, NULL }, + { 'U', specifier_user_id, NULL }, { 'u', specifier_user_name, NULL }, { 'm', specifier_machine_id, NULL }, diff --git a/src/shared/install.c b/src/shared/install.c index 17e4ea0b85..9b6464ba9d 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -855,36 +855,6 @@ static int config_parse_also( return 0; } -static int config_parse_user( - 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) { - - UnitFileInstallInfo *i = data; - char *printed; - int r; - - assert(filename); - assert(lvalue); - assert(rvalue); - - r = install_full_printf(i, rvalue, &printed); - if (r < 0) - return r; - - free(i->user); - i->user = printed; - - return 0; -} - static int config_parse_default_instance( const char *unit, const char *filename, @@ -933,7 +903,6 @@ static int unit_file_load( { "Install", "RequiredBy", config_parse_strv, 0, &info->required_by }, { "Install", "DefaultInstance", config_parse_default_instance, 0, info }, { "Install", "Also", config_parse_also, 0, c }, - { "Exec", "User", config_parse_user, 0, info }, {} }; diff --git a/src/shared/install.h b/src/shared/install.h index b1ab66f0d4..45a417df92 100644 --- a/src/shared/install.h +++ b/src/shared/install.h @@ -95,7 +95,6 @@ enum UnitFileType { struct UnitFileInstallInfo { char *name; char *path; - char *user; char **aliases; char **wanted_by; diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c index a8e5b6feee..c3973a316e 100644 --- a/src/test/test-unit-file.c +++ b/src/test/test-unit-file.c @@ -40,6 +40,7 @@ #include "string-util.h" #include "strv.h" #include "test-helper.h" +#include "user-util.h" #include "util.h" static int test_unit_file_get_set(void) { @@ -558,76 +559,66 @@ static void test_load_env_file_5(void) { static void test_install_printf(void) { char name[] = "name.service", - path[] = "/run/systemd/system/name.service", - user[] = "xxxx-no-such-user"; - UnitFileInstallInfo i = {name, path, user}; - UnitFileInstallInfo i2 = {name, path, NULL}; + path[] = "/run/systemd/system/name.service"; + UnitFileInstallInfo i = { .name = name, .path = path, }; + UnitFileInstallInfo i2 = { .name= name, .path = path, }; char name3[] = "name@inst.service", path3[] = "/run/systemd/system/name.service"; - UnitFileInstallInfo i3 = {name3, path3, user}; - UnitFileInstallInfo i4 = {name3, path3, NULL}; + UnitFileInstallInfo i3 = { .name = name3, .path = path3, }; + UnitFileInstallInfo i4 = { .name = name3, .path = path3, }; - _cleanup_free_ char *mid, *bid, *host; + _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL; assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); assert_se((host = gethostname_malloc())); + assert_se((user = getusername_malloc())); + assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0); #define expect(src, pattern, result) \ do { \ _cleanup_free_ char *t = NULL; \ _cleanup_free_ char \ *d1 = strdup(i.name), \ - *d2 = strdup(i.path), \ - *d3 = strdup(i.user); \ + *d2 = strdup(i.path); \ assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \ memzero(i.name, strlen(i.name)); \ memzero(i.path, strlen(i.path)); \ - memzero(i.user, strlen(i.user)); \ - assert_se(d1 && d2 && d3); \ + assert_se(d1 && d2); \ if (result) { \ printf("%s\n", t); \ - assert_se(streq(t, result)); \ - } else assert_se(t == NULL); \ + assert_se(streq(t, result)); \ + } else assert_se(t == NULL); \ strcpy(i.name, d1); \ strcpy(i.path, d2); \ - strcpy(i.user, d3); \ } while(false) - assert_se(setenv("USER", "root", 1) == 0); - expect(i, "%n", "name.service"); expect(i, "%N", "name"); expect(i, "%p", "name"); expect(i, "%i", ""); - expect(i, "%u", "xxxx-no-such-user"); - - DISABLE_WARNING_NONNULL; - expect(i, "%U", NULL); - REENABLE_WARNING; + expect(i, "%u", user); + expect(i, "%U", uid); expect(i, "%m", mid); expect(i, "%b", bid); expect(i, "%H", host); - expect(i2, "%u", "root"); - expect(i2, "%U", "0"); + expect(i2, "%u", user); + expect(i2, "%U", uid); expect(i3, "%n", "name@inst.service"); expect(i3, "%N", "name@inst"); expect(i3, "%p", "name"); - expect(i3, "%u", "xxxx-no-such-user"); - - DISABLE_WARNING_NONNULL; - expect(i3, "%U", NULL); - REENABLE_WARNING; + expect(i3, "%u", user); + expect(i3, "%U", uid); expect(i3, "%m", mid); expect(i3, "%b", bid); expect(i3, "%H", host); - expect(i4, "%u", "root"); - expect(i4, "%U", "0"); + expect(i4, "%u", user); + expect(i4, "%U", uid); } static uint64_t make_cap(int cap) { diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index 9db7853dd4..842ca40102 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -37,6 +37,7 @@ #include "unit-name.h" #include "unit-printf.h" #include "unit.h" +#include "user-util.h" #include "util.h" static void test_unit_name_is_valid(void) { @@ -193,15 +194,15 @@ static int test_unit_printf(void) { Unit *u, *u2; int r; - _cleanup_free_ char *mid, *bid, *host, *root_uid; - struct passwd *root; + _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL; assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid); assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid); - assert_se((host = gethostname_malloc())); - - assert_se((root = getpwnam("root"))); - assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0); + assert_se(host = gethostname_malloc()); + assert_se(user = getusername_malloc()); + assert_se(asprintf(&uid, UID_FMT, getuid())); + assert_se(get_home_dir(&home) >= 0); + assert_se(get_shell(&shell) >= 0); r = manager_new(MANAGER_USER, true, &m); if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) { @@ -222,8 +223,6 @@ static int test_unit_printf(void) { assert_se(streq(t, expected)); \ } - assert_se(setenv("USER", "root", 1) == 0); - assert_se(setenv("HOME", "/root", 1) == 0); assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0); assert_se(u = unit_new(m, sizeof(Service))); @@ -242,9 +241,9 @@ static int test_unit_printf(void) { expect(u, "%p", "blah"); expect(u, "%P", "blah"); expect(u, "%i", ""); - expect(u, "%u", root->pw_name); - expect(u, "%U", root_uid); - expect(u, "%h", root->pw_dir); + expect(u, "%u", user); + expect(u, "%U", uid); + expect(u, "%h", home); expect(u, "%m", mid); expect(u, "%b", bid); expect(u, "%H", host); @@ -262,9 +261,9 @@ static int test_unit_printf(void) { expect(u2, "%P", "blah"); expect(u2, "%i", "foo-foo"); expect(u2, "%I", "foo/foo"); - expect(u2, "%u", root->pw_name); - expect(u2, "%U", root_uid); - expect(u2, "%h", root->pw_dir); + expect(u2, "%u", user); + expect(u2, "%U", uid); + expect(u2, "%h", home); expect(u2, "%m", mid); expect(u2, "%b", bid); expect(u2, "%H", host); |