X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Futil.c;h=cbfac6ec3b3b22c1bebfa0ba6406497d14465d10;hp=2d4f2291932963fdfade7286741efe0d6d49deee;hb=b9b2b042c5564dfff730eeab43db9ac4bbe4c650;hpb=034a2a52ac0ec83e0229941d635d310b23eb04df diff --git a/src/util.c b/src/util.c index 2d4f22919..cbfac6ec3 100644 --- a/src/util.c +++ b/src/util.c @@ -54,6 +54,7 @@ #include #include #include +#include #include "macro.h" #include "util.h" @@ -5262,28 +5263,31 @@ 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) { struct passwd *p; - unsigned long lu; + uid_t u; 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 (safe_atolu(*username, &lu) >= 0) { + if (parse_uid(*username, &u) >= 0) { errno = 0; - p = getpwuid((uid_t) lu); + p = getpwuid(u); /* If there are multiple users with the same id, make * sure to leave $USER to the configured value instead @@ -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; } @@ -5384,7 +5432,10 @@ int get_files_in_directory(const char *path, char ***list) { char **l = NULL; assert(path); - assert(list); + + /* Returns all files in a directory in *list, and the number + * of files as return value. If list is NULL returns only the + * number */ d = opendir(path); for (;;) { @@ -5405,37 +5456,41 @@ int get_files_in_directory(const char *path, char ***list) { if (!dirent_is_file(de)) continue; - if ((unsigned) r >= n) { - char **t; + if (list) { + if ((unsigned) r >= n) { + char **t; - n = MAX(16, 2*r); - t = realloc(l, sizeof(char*) * n); - if (!t) { - r = -ENOMEM; - goto finish; - } + n = MAX(16, 2*r); + t = realloc(l, sizeof(char*) * n); + if (!t) { + r = -ENOMEM; + goto finish; + } - l = t; - } + l = t; + } - assert((unsigned) r < n); + assert((unsigned) r < n); - l[r] = strdup(de->d_name); - if (!l[r]) { - r = -ENOMEM; - goto finish; - } + l[r] = strdup(de->d_name); + if (!l[r]) { + r = -ENOMEM; + goto finish; + } - l[++r] = NULL; + l[++r] = NULL; + } else + r++; } finish: if (d) closedir(d); - if (r >= 0) - *list = l; - else + if (r >= 0) { + if (list) + *list = l; + } else strv_free(l); return r;