X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Futil.c;h=f75df7b5116c68662decce5ac1f27a6a0897f0c6;hb=1cccf435694675ca1584811179784fc2292e351b;hp=270c7dac794abb0a423b1caf708fa5914fa4cac6;hpb=bde7f9072109aaf298fe35de59a61b1eb026bf51;p=elogind.git diff --git a/src/util.c b/src/util.c index 270c7dac7..f75df7b51 100644 --- a/src/util.c +++ b/src/util.c @@ -5188,6 +5188,52 @@ int socket_from_display(const char *display, char **path) { return 0; } +int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) { + struct passwd *p; + unsigned long lu; + + 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"; + return 0; + } + + if (safe_atolu(*username, &lu) >= 0) { + errno = 0; + p = getpwuid((uid_t) lu); + + /* If there are multiple users with the same id, make + * sure to leave $USER to the configured value instead + * of the first occurrence in the database. However if + * the uid was configured by a numeric uid, then let's + * pick the real username from /etc/passwd. */ + if (p) + *username = p->pw_name; + } else { + errno = 0; + p = getpwnam(*username); + } + + if (!p) + return errno != 0 ? -errno : -ESRCH; + + *uid = p->pw_uid; + *gid = p->pw_gid; + *home = p->pw_dir; + return 0; +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime",