int lxc_attach_run_shell(void* payload)
{
uid_t uid;
- struct passwd *passwd;
+ struct passwd pwent;
+ struct passwd *pwentp = NULL;
char *user_shell;
+ char *buf;
+ size_t bufsize;
+ int ret;
/* Ignore payload parameter. */
(void)payload;
uid = getuid();
- passwd = getpwuid(uid);
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1)
+ bufsize = 1024;
+
+ buf = malloc(bufsize);
+ if (buf) {
+ ret = getpwuid_r(uid, &pwent, buf, bufsize, &pwentp);
+ if (!pwentp) {
+ if (ret == 0)
+ WARN("Could not find matched password record.");
+
+ WARN("Failed to get password record - %u", uid);
+ }
+ }
/* This probably happens because of incompatible nss implementations in
* host and container (remember, this code is still using the host's
* the information by spawning a [getent passwd uid] process and parsing
* the result.
*/
- if (!passwd)
+ if (!pwentp)
user_shell = lxc_attach_getpwshell(uid);
else
- user_shell = passwd->pw_shell;
+ user_shell = pwent.pw_shell;
if (user_shell)
execlp(user_shell, user_shell, (char *)NULL);
*/
execlp("/bin/sh", "/bin/sh", (char *)NULL);
SYSERROR("Failed to execute shell");
- if (!passwd)
+ if (!pwentp)
free(user_shell);
+ free(buf);
return -1;
}
static char *get_username(void)
{
- struct passwd *pwd;
+ struct passwd pwent;
+ struct passwd *pwentp = NULL;
+ char *buf;
+ char *username;
+ size_t bufsize;
+ int ret;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1)
+ bufsize = 1024;
+
+ buf = malloc(bufsize);
+ if (!buf)
+ return NULL;
+
+ ret = getpwuid_r(getuid(), &pwent, buf, bufsize, &pwentp);
+ if (!pwentp) {
+ if (ret == 0)
+ usernic_error("%s", "Could not find matched password record\n");
- pwd = getpwuid(getuid());
- if (!pwd) {
- usernic_error("Failed to get username: %s\n", strerror(errno));
+ usernic_error("Failed to get username: %s(%u)\n", strerror(errno), getuid());
+ free(buf);
return NULL;
}
- return pwd->pw_name;
+ username = strdup(pwent.pw_name);
+ free(buf);
+
+ return username;
}
static void free_groupnames(char **groupnames)
}
n = get_alloted(me, args.type, args.link, &alloted);
+ free(me);
if (request == LXC_USERNIC_DELETE) {
int ret;
static int find_default_map(void)
{
- struct passwd *p = getpwuid(getuid());
- if (!p)
+ struct passwd pwent;
+ struct passwd *pwentp = NULL;
+ char *buf;
+ size_t bufsize;
+ int ret;
+
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1)
+ bufsize = 1024;
+
+ buf = malloc(bufsize);
+ if (!buf)
return -1;
- if (read_default_map(subuidfile, ID_TYPE_UID, p->pw_name) < 0)
+
+ ret = getpwuid_r(getuid(), &pwent, buf, bufsize, &pwentp);
+ if (!pwentp) {
+ if (ret == 0)
+ printf("WARN: could not find matched password record\n");
+
+ printf("Failed to get password record - %u\n", getuid());
+ free(buf);
return -1;
- if (read_default_map(subgidfile, ID_TYPE_GID, p->pw_name) < 0)
+ }
+
+ if (read_default_map(subuidfile, ID_TYPE_UID, pwent.pw_name) < 0) {
+ free(buf);
return -1;
- return 0;
+ }
+
+ if (read_default_map(subgidfile, ID_TYPE_GID, pwent.pw_name) < 0) {
+ free(buf);
+ return -1;
+ }
+
+ free(buf);
+ return 0;
}
int main(int argc, char *argv[])
/* not thread-safe, do not use from api without first forking */
static char *getuname(void)
{
- struct passwd *result;
+ struct passwd pwent;
+ struct passwd *pwentp = NULL;
+ char *buf;
+ char *username;
+ size_t bufsize;
+ int ret;
- result = getpwuid(geteuid());
- if (!result)
+ bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
+ if (bufsize == -1)
+ bufsize = 1024;
+
+ buf = malloc(bufsize);
+ if (!buf)
return NULL;
- return strdup(result->pw_name);
+ ret = getpwuid_r(geteuid(), &pwent, buf, bufsize, &pwentp);
+ if (!pwentp) {
+ if (ret == 0)
+ WARN("Could not find matched password record.");
+
+ ERROR("Failed to get password record - %u", geteuid());
+ free(buf);
+ return NULL;
+ }
+
+ username = strdup(pwent.pw_name);
+ free(buf);
+
+ return username;
}
/* not thread-safe, do not use from api without first forking */