From 0aa3349aa353c318790ebc8287ae3f0122bbe611 Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Mon, 5 Jun 2023 11:22:36 +0200 Subject: [PATCH] Implement getpwuid_r --- fakeid.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/fakeid.c b/fakeid.c index 5cf8afb..2e4f51f 100644 --- a/fakeid.c +++ b/fakeid.c @@ -38,6 +38,9 @@ struct passwd *getpwuid(uid_t uid) { return NULL; } struct passwd *pass = getpwuid(uid); + if (pass == NULL) { + return NULL; + } char *name = getenv("USER"); if (name == NULL) { fprintf(stderr, "Could not find the USER environment variable. Using the real username.\n"); @@ -46,3 +49,28 @@ struct passwd *getpwuid(uid_t uid) { pass->pw_name = name; return pass; } + +int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res) { + int prev_err = errno; + *res = NULL; + struct passwd *pass = getpwuid(uid); + if (pass == NULL || errno != prev_err) { + return errno; + } + memcpy(pw, pass, sizeof(struct passwd)); + size_t name_len = strlen(pass->pw_name) + 1; + size_t passwd_len = strlen(pass->pw_passwd) + 1; + size_t gecos_len = strlen(pass->pw_gecos) + 1; + size_t dir_len = strlen(pass->pw_dir) + 1; + size_t shell_len = strlen(pass->pw_shell) + 1; + if ((name_len + passwd_len + gecos_len + dir_len + shell_len) > size) { + return ERANGE; + } + pw->pw_name = memcpy(buf, pass->pw_name, name_len); + pw->pw_passwd = memcpy(buf + name_len, pass->pw_passwd, passwd_len); + pw->pw_gecos = memcpy(buf + name_len + passwd_len, pass->pw_gecos, gecos_len); + pw->pw_dir = memcpy(buf + name_len + passwd_len + gecos_len, pass->pw_dir, dir_len); + pw->pw_shell = memcpy(buf + name_len + passwd_len + gecos_len + dir_len, pass->pw_shell, shell_len); + *res = pw; + return 0; +}