Hi,
I noticed that setpassent(1) probably doesn't work as intended, as this
program should open the spwd.db file once, not four times?
int main() {
setpassent(1);
getpwnam(root); getpwnam(root); getpwuid(0); getpwuid(0);
return 0;
}
It seems to be due to faulty logic in libc/gen/getpwent.c. In short
...
savedb = _pw_db;
if (!_pw_db !__initdb())
...
_pw_db begin as NULL
so savedb is set to NULL
_pw_db is NULL and __initdb() is run, _pw_db is set
...
if (savedb != _pw_db || !_pw_stayopen) {
...
savedb is still NULL, _pwd_db is not, so the first condition is true
_pw_db get closed, and set to NULL
This following patch fixes this.
--- lib/libc/gen/getpwent.c.origThu Nov 14 21:06:13 2013
+++ lib/libc/gen/getpwent.c Thu Nov 14 21:18:45 2013
@@ -708,10 +708,8 @@
{
struct passwd *pwret = NULL;
int flags = 0, *flagsp;
- DB *savedb;
_THREAD_PRIVATE_MUTEX_LOCK(pw);
- savedb = _pw_db;
if (!_pw_db !__initdb())
goto fail;
@@ -728,7 +726,7 @@
if (!pwret)
pwret = _pwhashbyname(name, buf, buflen, pw, flagsp);
- if (savedb != _pw_db || !_pw_stayopen) {
+ if (!_pw_stayopen) {
(void)(_pw_db-close)(_pw_db);
_pw_db = NULL;
}
@@ -755,10 +753,8 @@
{
struct passwd *pwret = NULL;
int flags = 0, *flagsp;
- DB *savedb;
_THREAD_PRIVATE_MUTEX_LOCK(pw);
- savedb = _pw_db;
if (!_pw_db !__initdb())
goto fail;
@@ -775,7 +771,7 @@
if (!pwret)
pwret = _pwhashbyuid(uid, buf, buflen, pw, flagsp);
- if (savedb != _pw_db || !_pw_stayopen) {
+ if (!_pw_stayopen) {
(void)(_pw_db-close)(_pw_db);
_pw_db = NULL;
}