Two problems getting user and group info from /etc/{passwd,group}
q q
miska0000@yahoo.com
Fri Apr 11 20:41:00 GMT 2014
Dear Cygwin developers,
Can you please take a look? - We came across a couple problems (times two, because they're identical for /etc/group as well):
1. When '/etc/passwd' gets reloaded, it can't add the last (default) line for uid=-1 because pretty_ls[] has already been parsed (':'s replaced with '\0'), and can't be parsed again.
2. When there's fork(), a fresh copy of the pretty_ls seems to be loaded, which does not have '\0's in place of ':'s, while the parsed addressed are kept on heap and are still valid.
NOTE. The default entry (uid=-1) is needed in case when code runs from a service account(NT SERVICE\...), which can't map to any POSIX UID/GID, so they fail back to -1.
The exposition is below, for each bug (WARNING: BUG1 will cause /etc/passwd to be "touch"ed):
$ gcc -DBUG1 pwd.c
$ ./a.exe
pw_name = (0x6118ad2c)????????
pw_passwd = (0x6118ad35)*
pw_uid = 4294967295
pw_gid = 4294967295
pw_gecos = (0x6118ad3d)
pw_dir = (0x6118ad3e)
pw_shell = (0x6118ad3f)
pwd = NULL
$ gcc -DBUG2 pwd.c
$ ./a.exe
pw_name = (0x6118ad2c)????????
pw_passwd = (0x6118ad35)*
pw_uid = 4294967295
pw_gid = 4294967295
pw_gecos = (0x6118ad3d)
pw_dir = (0x6118ad3e)
pw_shell = (0x6118ad3f)
pw_name = (0x6118ad2c)????????:*:-1:-1:::
pw_passwd = (0x6118ad35)*:-1:-1:::
pw_uid = 4294967295
pw_gid = 4294967295
pw_gecos = (0x6118ad3d)::
pw_dir = (0x6118ad3e):
pw_shell = (0x6118ad3f)
Best regards,
Q.
---------------------------------------
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <utime.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
//#define BUG1
//#define BUG2
static void s_GetPwUid(uid_t uid)
{
const struct passwd* pwd = getpwuid(uid);
if (pwd) {
printf("pw_name = (%p)%s\n"
"pw_passwd = (%p)%s\n"
"pw_uid = %u\n"
"pw_gid = %u\n"
"pw_gecos = (%p)%s\n"
"pw_dir = (%p)%s\n"
"pw_shell = (%p)%s\n\n",
pwd->pw_name, pwd->pw_name ? pwd->pw_name : "NULL",
pwd->pw_passwd, pwd->pw_passwd ? pwd->pw_passwd : "NULL",
(unsigned int) pwd->pw_uid,
(unsigned int) pwd->pw_gid,
pwd->pw_gecos, pwd->pw_gecos ? pwd->pw_gecos : "NULL",
pwd->pw_dir, pwd->pw_dir ? pwd->pw_dir : "NULL",
pwd->pw_shell, pwd->pw_shell ? pwd->pw_shell : "NULL");
} else {
printf("pwd = NULL\n\n");
}
}
int main(void)
{
s_GetPwUid(-1);
#ifdef BUG1
{
time_t t;
struct timeval tv[2];
sleep(2);
t = time(0);
memset(tv, 0, sizeof(tv));
tv[0].tv_sec = t;
tv[1].tv_sec = t;
utimes("/etc/passwd", tv);
s_GetPwUid(-1);
}
#endif
#ifdef BUG2
if (fork())
return 0;
s_GetPwUid(-1);
#endif
return 0;
}
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
More information about the Cygwin
mailing list