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;
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) {
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;
}
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(
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;
m = reply = NULL;
}
+ ret = 0;
+
finish:
if (m)
dbus_message_unref(m);
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;
m = reply = NULL;
}
+ ret = 0;
+
finish:
if (m)
dbus_message_unref(m);
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;
m = reply = NULL;
}
+ ret = 0;
+
finish:
if (m)
dbus_message_unref(m);
}
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) {
}
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;
}
}
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;
}
#include <sys/time.h>
#include <linux/rtc.h>
#include <glob.h>
+#include <grp.h>
#include "macro.h"
#include "util.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;
}
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;
}
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);