X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Futil.c;h=43ec62eac653d67a10190187c82eb0c76a551934;hb=8351ceaea9480d9c2979aa2ff0f4982cfdfef58d;hp=cef6dbb732f48201c3c26fc21e2804dfd24e6c56;hpb=4a0ff4780d4e5e3927f1cf574e05979ddeef8ae1;p=elogind.git diff --git a/src/shared/util.c b/src/shared/util.c index cef6dbb73..43ec62eac 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -3078,26 +3078,22 @@ bool hostname_is_set(void) { return !isempty(u.nodename) && !streq(u.nodename, "(none)"); } -char* getlogname_malloc(void) { - uid_t uid; + +static char *lookup_uid(uid_t uid) { long bufsize; char *buf, *name; struct passwd pwbuf, *pw = NULL; - struct stat st; - - if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0) - uid = st.st_uid; - else - uid = getuid(); /* Shortcut things to avoid NSS lookups */ if (uid == 0) return strdup("root"); - if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) <= 0) + bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); + if (bufsize <= 0) bufsize = 4096; - if (!(buf = malloc(bufsize))) + buf = malloc(bufsize); + if (!buf) return NULL; if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw) { @@ -3114,6 +3110,28 @@ char* getlogname_malloc(void) { return name; } +char* getlogname_malloc(void) { + uid_t uid; + struct stat st; + + if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0) + uid = st.st_uid; + else + uid = getuid(); + + return lookup_uid(uid); +} + +char *getusername_malloc(void) { + const char *e; + + e = getenv("USER"); + if (e) + return strdup(e); + + return lookup_uid(getuid()); +} + int getttyname_malloc(int fd, char **r) { char path[PATH_MAX], *c; int k; @@ -4887,7 +4905,12 @@ 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) { +int get_user_creds( + const char **username, + uid_t *uid, gid_t *gid, + const char **home, + const char **shell) { + struct passwd *p; uid_t u; @@ -4908,6 +4931,10 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h if (home) *home = "/root"; + + if (shell) + *shell = "/bin/sh"; + return 0; } @@ -4939,6 +4966,9 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h if (home) *home = p->pw_dir; + if (shell) + *shell = p->pw_shell; + return 0; } @@ -5875,3 +5905,97 @@ int make_console_stdio(void) { return 0; } + +int get_home_dir(char **_h) { + char *h; + const char *e; + uid_t u; + struct passwd *p; + + assert(_h); + + /* Take the user specified one */ + e = getenv("HOME"); + if (e) { + h = strdup(e); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + h = strdup("/root"); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno ? -errno : -ENOENT; + + if (!path_is_absolute(p->pw_dir)) + return -EINVAL; + + h = strdup(p->pw_dir); + if (!h) + return -ENOMEM; + + *_h = h; + return 0; +} + +int get_shell(char **_sh) { + char *sh; + const char *e; + uid_t u; + struct passwd *p; + + assert(_sh); + + /* Take the user specified one */ + e = getenv("SHELL"); + if (e) { + sh = strdup(e); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; + } + + /* Hardcode home directory for root to avoid NSS */ + u = getuid(); + if (u == 0) { + sh = strdup("/bin/sh"); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; + } + + /* Check the database... */ + errno = 0; + p = getpwuid(u); + if (!p) + return errno ? -errno : -ESRCH; + + if (!path_is_absolute(p->pw_shell)) + return -EINVAL; + + sh = strdup(p->pw_shell); + if (!sh) + return -ENOMEM; + + *_sh = sh; + return 0; +}