diff options
-rw-r--r-- | src/execute.c | 42 | ||||
-rw-r--r-- | src/loginctl.c | 70 | ||||
-rw-r--r-- | src/logind.c | 13 | ||||
-rw-r--r-- | src/tmpfiles.c | 30 | ||||
-rw-r--r-- | src/util.c | 66 | ||||
-rw-r--r-- | src/util.h | 1 |
6 files changed, 105 insertions, 117 deletions
diff --git a/src/execute.c b/src/execute.c index 40af7d65f1..7b2567976d 100644 --- a/src/execute.c +++ b/src/execute.c @@ -549,36 +549,6 @@ static int restore_confirm_stdio(const ExecContext *context, return 0; } -static int get_group_creds(const char *groupname, gid_t *gid) { - struct group *g; - gid_t id; - - assert(groupname); - assert(gid); - - /* We enforce some special rules for gid=0: in order to avoid - * NSS lookups for root we hardcode its data. */ - - if (streq(groupname, "root") || streq(groupname, "0")) { - *gid = 0; - return 0; - } - - if (parse_gid(groupname, &id) >= 0) { - errno = 0; - g = getgrgid(id); - } else { - errno = 0; - g = getgrnam(groupname); - } - - if (!g) - return errno != 0 ? -errno : -ESRCH; - - *gid = g->gr_gid; - return 0; -} - static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) { bool keep_groups = false; int r; @@ -590,9 +560,12 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_ if (context->group || username) { - if (context->group) - if ((r = get_group_creds(context->group, &gid)) < 0) + if (context->group) { + const char *g = context->group; + + if ((r = get_group_creds(&g, &gid)) < 0) return r; + } /* First step, initialize groups from /etc/groups */ if (username && gid != 0) { @@ -627,13 +600,16 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_ k = 0; STRV_FOREACH(i, context->supplementary_groups) { + const char *g; if (k >= ngroups_max) { free(gids); return -E2BIG; } - if ((r = get_group_creds(*i, gids+k)) < 0) { + g = *i; + r = get_group_creds(&g, gids+k); + if (r < 0) { free(gids); return r; } diff --git a/src/loginctl.c b/src/loginctl.c index 08ee804f43..53058d07a7 100644 --- a/src/loginctl.c +++ b/src/loginctl.c @@ -1061,17 +1061,11 @@ static int show(DBusConnection *bus, char **args, unsigned n) { uid_t uid; uint32_t u; - if (parse_uid(args[i], &uid) < 0) { - struct passwd *pw; - - pw = getpwnam(args[i]); - if (!pw) { - log_error("User %s unknown.", args[i]); - ret = -ENOENT; - goto finish; - } - - uid = pw->pw_uid; + r = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (r < 0) { + log_error("User %s unknown.", args[i]); + r = -ENOENT; + goto finish; } m = dbus_message_new_method_call( @@ -1298,18 +1292,10 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) { goto finish; } - if (parse_uid(args[i], &uid) < 0) { - struct passwd *pw; - - errno = 0; - pw = getpwnam(args[i]); - if (!pw) { - ret = errno ? -errno : -ENOENT; - log_error("Failed to resolve user %s: %s", args[i], strerror(-ret)); - goto finish; - } - - uid = pw->pw_uid; + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to resolve user %s: %s", args[i], strerror(-ret)); + goto finish; } u = (uint32_t) uid; @@ -1335,6 +1321,8 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) { m = reply = NULL; } + ret = 0; + finish: if (m) dbus_message_unref(m); @@ -1373,18 +1361,10 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) { goto finish; } - if (parse_uid(args[i], &uid) < 0) { - struct passwd *pw; - - errno = 0; - pw = getpwnam(args[i]); - if (!pw) { - ret = errno ? -errno : -ENOENT; - log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); - goto finish; - } - - uid = pw->pw_uid; + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; } u = (uint32_t) uid; @@ -1408,6 +1388,8 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) { m = reply = NULL; } + ret = 0; + finish: if (m) dbus_message_unref(m); @@ -1449,18 +1431,10 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) { goto finish; } - if (parse_uid(args[i], &uid) < 0) { - struct passwd *pw; - - errno = 0; - pw = getpwnam(args[i]); - if (!pw) { - ret = errno ? -errno : -ENOENT; - log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); - goto finish; - } - - uid = pw->pw_uid; + ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL); + if (ret < 0) { + log_error("Failed to look up user %s: %s", args[i], strerror(-ret)); + goto finish; } u = (uint32_t) uid; @@ -1485,6 +1459,8 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) { m = reply = NULL; } + ret = 0; + finish: if (m) dbus_message_unref(m); diff --git a/src/logind.c b/src/logind.c index a081501a8c..8b99065b23 100644 --- a/src/logind.c +++ b/src/logind.c @@ -239,17 +239,18 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User ** } int manager_add_user_by_name(Manager *m, const char *name, User **_user) { - struct passwd *p; + uid_t uid; + gid_t gid; + int r; assert(m); assert(name); - errno = 0; - p = getpwnam(name); - if (!p) - return errno ? -errno : -ENOENT; + r = get_user_creds(&name, &uid, &gid, NULL); + if (r < 0) + return r; - return manager_add_user(m, p->pw_uid, p->pw_gid, name, _user); + return manager_add_user(m, uid, gid, name, _user); } int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) { diff --git a/src/tmpfiles.c b/src/tmpfiles.c index a1b2f8b1d2..3a1985a363 100644 --- a/src/tmpfiles.c +++ b/src/tmpfiles.c @@ -757,18 +757,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { } if (user && !streq(user, "-")) { - uid_t uid; - struct passwd *p; - - if (streq(user, "root") || streq(user, "0")) - i->uid = 0; - else if (parse_uid(user, &uid) >= 0) - i->uid = uid; - else if ((p = getpwnam(user))) - i->uid = p->pw_uid; - else { + const char *u = user; + + r = get_user_creds(&u, &i->uid, NULL, NULL); + if (r < 0) { log_error("[%s:%u] Unknown user '%s'.", fname, line, user); - r = -ENOENT; goto finish; } @@ -776,18 +769,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { } if (group && !streq(group, "-")) { - gid_t gid; - struct group *g; - - if (streq(group, "root") || streq(group, "0")) - i->gid = 0; - else if (parse_gid(group, &gid) >= 0) - i->gid = gid; - else if ((g = getgrnam(group))) - i->gid = g->gr_gid; - else { + const char *g = group; + + r = get_group_creds(&g, &i->gid); + if (r < 0) { log_error("[%s:%u] Unknown group '%s'.", fname, line, group); - r = -ENOENT; goto finish; } diff --git a/src/util.c b/src/util.c index 3a82ef7600..45b578bd03 100644 --- a/src/util.c +++ b/src/util.c @@ -54,6 +54,7 @@ #include <sys/time.h> #include <linux/rtc.h> #include <glob.h> +#include <grp.h> #include "macro.h" #include "util.h" @@ -5266,18 +5267,21 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h assert(username); assert(*username); - assert(uid); - assert(gid); - assert(home); /* We enforce some special rules for uid=0: in order to avoid * NSS lookups for root we hardcode its data. */ if (streq(*username, "root") || streq(*username, "0")) { *username = "root"; - *uid = 0; - *gid = 0; - *home = "/root"; + + if (uid) + *uid = 0; + + if (gid) + *gid = 0; + + if (home) + *home = "/root"; return 0; } @@ -5300,9 +5304,53 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h if (!p) return errno != 0 ? -errno : -ESRCH; - *uid = p->pw_uid; - *gid = p->pw_gid; - *home = p->pw_dir; + if (uid) + *uid = p->pw_uid; + + if (gid) + *gid = p->pw_gid; + + if (home) + *home = p->pw_dir; + + return 0; +} + +int get_group_creds(const char **groupname, gid_t *gid) { + struct group *g; + gid_t id; + + assert(groupname); + + /* We enforce some special rules for gid=0: in order to avoid + * NSS lookups for root we hardcode its data. */ + + if (streq(*groupname, "root") || streq(*groupname, "0")) { + *groupname = "root"; + + if (gid) + *gid = 0; + + return 0; + } + + if (parse_gid(*groupname, &id) >= 0) { + errno = 0; + g = getgrgid(id); + + if (g) + *groupname = g->gr_name; + } else { + errno = 0; + g = getgrnam(*groupname); + } + + if (!g) + return errno != 0 ? -errno : -ESRCH; + + if (gid) + *gid = g->gr_gid; + return 0; } diff --git a/src/util.h b/src/util.h index 9537d130d3..bf5703c5aa 100644 --- a/src/util.h +++ b/src/util.h @@ -449,6 +449,7 @@ bool display_is_local(const char *display); int socket_from_display(const char *display, char **path); int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home); +int get_group_creds(const char **groupname, gid_t *gid); int glob_exists(const char *path); |