From 2765e7aa3e603972b38fa763d0cd3f398443f79d Mon Sep 17 00:00:00 2001 From: Marc Fiuczynski Date: Mon, 3 Jan 2005 16:31:48 +0000 Subject: [PATCH] Use getpwnam_r to work around problems with getpwnam on FC3 and Gentoo boxes. Fix suggested by Gao Chan from Tsinghua. --- src/vsh.c | 67 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/src/vsh.c b/src/vsh.c index 0fdd59c..084e1cc 100644 --- a/src/vsh.c +++ b/src/vsh.c @@ -394,12 +394,28 @@ static int sandbox_processes(uid_t uid, unsigned remove_cap) void runas_slice_user(char *username) { - struct passwd *pwd; + struct passwd pwdd, *pwd = &pwdd, *result; + char *pwdBuffer; char *home_env, *logname_env, *mail_env, *shell_env, *user_env; int home_len, logname_len, mail_len, shell_len, user_len; + long pwdBuffer_len; static char *envp[10]; - if ((pwd = getpwnam(username)) == NULL) { + + pwdBuffer_len = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pwdBuffer_len == -1) { + perror("vserver: _SC_GETPW_R_SIZE_MAX not defined "); + exit(1); + } + + pwdBuffer = (char*)malloc(pwdBuffer_len); + if (pwdBuffer == NULL) { + perror("vserver: malloc error "); + exit(1); + } + + errno = 0; + if ((getpwnam_r(username,pwd,pwdBuffer,pwdBuffer_len, &result) != 0) || (errno != 0)) { perror("vserver: getpwnam error "); exit(1); } @@ -470,16 +486,30 @@ void runas_slice_user(char *username) } } - - void slice_enter(char *context) { - struct passwd *pwd; + struct passwd pwdd, *pwd = &pwdd, *result; + char *pwdBuffer; + long pwdBuffer_len; unsigned remove_cap; uid_t uid; - if ((pwd = getpwnam(context)) == NULL) { + pwdBuffer_len = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pwdBuffer_len == -1) { + perror("vserver: _SC_GETPW_R_SIZE_MAX not defined "); + exit(1); + } + + pwdBuffer = (char*)malloc(pwdBuffer_len); + if (pwdBuffer == NULL) { + perror("vserver: malloc error "); + exit(1); + } + + errno = 0; + if ((getpwnam_r(context,pwd,pwdBuffer,pwdBuffer_len, &result) != 0) || (errno != 0)) { fprintf(stderr,"vserver: getpwname(%s) failed",context); + perror(""); exit(2); } @@ -521,15 +551,13 @@ enum EXIT_ENOENT = 127 }; -extern void slice_enter(char *); -extern void runas_slice_user(char *); - int main(int argc, char **argv) { - char *context, *username, *shell; - struct passwd *pwd; + struct passwd pwdd, *pwd = &pwdd, *result; + char *context, *username, *shell, *pwdBuffer; + long pwdBuffer_len; uid_t uid; - int index, i; + int index, i; if (argv[0][0]=='-') index = 1; @@ -561,7 +589,20 @@ int main(int argc, char **argv) /* With the uid/gid appropriately set. Let's figure out what the * shell in the vserver's /etc/passwd is for the given username. */ - if ((pwd = getpwnam(username)) == NULL) { + + pwdBuffer_len = sysconf(_SC_GETPW_R_SIZE_MAX); + if (pwdBuffer_len == -1) { + perror("vserver: _SC_GETPW_R_SIZE_MAX not defined "); + exit(1); + } + pwdBuffer = (char*)malloc(pwdBuffer_len); + if (pwdBuffer == NULL) { + perror("vserver: malloc error "); + exit(1); + } + + errno = 0; + if ((getpwnam_r(username,pwd,pwdBuffer,pwdBuffer_len, &result) != 0) || (errno != 0)) { fprintf(stderr,"vsh: getpwnam error failed for %s\n",username); exit(1); } -- 2.43.0