Module Name: src
Committed By: christos
Date: Thu Mar 29 13:05:10 UTC 2012
Modified Files:
src/lib/libc/gen: getgrent.c getpwent.c
Log Message:
PR?40728: W. Stukenbrock: Fix various issues with NIS-netgroups in users
and groups.
To generate a diff of this commit:
cvs rdiff -u -r1.65 -r1.66 src/lib/libc/gen/getgrent.c
cvs rdiff -u -r1.77 -r1.78 src/lib/libc/gen/getpwent.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/gen/getgrent.c
diff -u src/lib/libc/gen/getgrent.c:1.65 src/lib/libc/gen/getgrent.c:1.66
--- src/lib/libc/gen/getgrent.c:1.65 Tue Mar 13 17:13:35 2012
+++ src/lib/libc/gen/getgrent.c Thu Mar 29 09:05:10 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: getgrent.c,v 1.65 2012/03/13 21:13:35 christos Exp $ */
+/* $NetBSD: getgrent.c,v 1.66 2012/03/29 13:05:10 christos Exp $ */
/*-
* Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
#if 0
static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
#else
-__RCSID("$NetBSD: getgrent.c,v 1.65 2012/03/13 21:13:35 christos Exp $");
+__RCSID("$NetBSD: getgrent.c,v 1.66 2012/03/29 13:05:10 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -1190,9 +1190,17 @@ _nis_getgrgid_r(void *nsrv, void *nscb,
_DIAGASSERT(result != NULL);
*result = NULL;
- memset(&state, 0, sizeof(state));
- rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
- __grend_nis(&state);
+/* remark: we run under a global mutex inside of this module ... */
+ if (_nis_state.stayopen)
+ { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
+ rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, NULL, gid);
+ }
+ else
+ {
+ memset(&state, 0, sizeof(state));
+ rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
+ __grend_nis(&state);
+ }
if (rv == NS_SUCCESS)
*result = grp;
return rv;
@@ -1242,9 +1250,17 @@ _nis_getgrnam_r(void *nsrv, void *nscb,
_DIAGASSERT(result != NULL);
*result = NULL;
- memset(&state, 0, sizeof(state));
- rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
- __grend_nis(&state);
+/* remark: we run under a global mutex inside of this module ... */
+ if (_nis_state.stayopen)
+ { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
+ rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, name, 0);
+ }
+ else
+ {
+ memset(&state, 0, sizeof(state));
+ rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
+ __grend_nis(&state);
+ }
if (rv == NS_SUCCESS)
*result = grp;
return rv;
Index: src/lib/libc/gen/getpwent.c
diff -u src/lib/libc/gen/getpwent.c:1.77 src/lib/libc/gen/getpwent.c:1.78
--- src/lib/libc/gen/getpwent.c:1.77 Tue Mar 23 16:28:59 2010
+++ src/lib/libc/gen/getpwent.c Thu Mar 29 09:05:10 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: getpwent.c,v 1.77 2010/03/23 20:28:59 drochner Exp $ */
+/* $NetBSD: getpwent.c,v 1.78 2012/03/29 13:05:10 christos Exp $ */
/*-
* Copyright (c) 1997-2000, 2004-2005 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
#if 0
static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
#else
-__RCSID("$NetBSD: getpwent.c,v 1.77 2010/03/23 20:28:59 drochner Exp $");
+__RCSID("$NetBSD: getpwent.c,v 1.78 2012/03/29 13:05:10 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -1126,7 +1126,7 @@ struct nis_state {
char *current; /* current first/next match */
int currentlen; /* length of _nis_current */
enum { /* shadow map type */
- NISMAP_UNKNOWN, /* unknown ... */
+ NISMAP_UNKNOWN = 0, /* unknown ... */
NISMAP_NONE, /* none: use "passwd.by*" */
NISMAP_ADJUNCT, /* pw_passwd from "passwd.adjunct.*" */
NISMAP_MASTER /* all from "master.passwd.by*" */
@@ -1138,11 +1138,17 @@ static struct nis_state _nis_state;
static struct passwd _nis_passwd;
static char _nis_passwdbuf[_GETPW_R_SIZE_MAX];
+static const char __nis_pw_n_1[] = "master.passwd.byname";
+static const char __nis_pw_n_2[] = "passwd.byname";
+static const char __nis_pw_u_1[] = "master.passwd.byuid";
+static const char __nis_pw_u_2[] = "passwd.byuid";
+
+static const char * const __nis_pw_n_map[4] = { __nis_pw_n_2, __nis_pw_n_2, __nis_pw_n_2, __nis_pw_n_1 };
+static const char * const __nis_pw_u_map[4] = { __nis_pw_u_2, __nis_pw_u_2, __nis_pw_u_2, __nis_pw_u_1 };
+
/* macros for deciding which NIS maps to use. */
-#define PASSWD_BYNAME(x) ((x)->maptype == NISMAP_MASTER \
- ? "master.passwd.byname" : "passwd.byname")
-#define PASSWD_BYUID(x) ((x)->maptype == NISMAP_MASTER \
- ? "master.passwd.byuid" : "passwd.byuid")
+#define PASSWD_BYNAME(x) ((x)->maptype == NISMAP_MASTER ? __nis_pw_n_1 : __nis_pw_n_2)
+#define PASSWD_BYUID(x) ((x)->maptype == NISMAP_MASTER ? __nis_pw_u_1 : __nis_pw_u_2)
static int
_nis_start(struct nis_state *state)
@@ -1263,7 +1269,7 @@ _nis_parse(const char *entry, struct pas
*/
static int
_nis_pwscan(int *retval, struct passwd *pw, char *buffer, size_t buflen,
- struct nis_state *state, const char *map)
+ struct nis_state *state, const char * const *map_arr)
{
char *data;
int nisr, rv, datalen;
@@ -1272,7 +1278,7 @@ _nis_pwscan(int *retval, struct passwd *
_DIAGASSERT(pw != NULL);
_DIAGASSERT(buffer != NULL);
_DIAGASSERT(state != NULL);
- _DIAGASSERT(map != NULL);
+ _DIAGASSERT(map_arr != NULL);
*retval = 0;
@@ -1284,9 +1290,10 @@ _nis_pwscan(int *retval, struct passwd *
data = NULL;
rv = NS_NOTFOUND;
+ _DIAGASSERT(state->maptype > 0 && state->maptype < sizeof(map_arr)/sizeof(const char*));
/* search map */
- nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
+ nisr = yp_match(state->domain, map_arr[state->maptype], buffer, (int)strlen(buffer),
&data, &datalen);
switch (nisr) {
case 0:
@@ -1521,7 +1528,7 @@ _nis_getpwuid(void *nsrv, void *nscb, va
snprintf(_nis_passwdbuf, sizeof(_nis_passwdbuf), "%u", (unsigned int)uid);
rv = _nis_pwscan(&rerror, &_nis_passwd,
_nis_passwdbuf, sizeof(_nis_passwdbuf),
- &_nis_state, PASSWD_BYUID(&_nis_state));
+ &_nis_state, __nis_pw_u_map);
if (!_nis_state.stayopen)
_nis_end(&_nis_state);
if (rv == NS_SUCCESS && uid == _nis_passwd.pw_uid)
@@ -1549,14 +1556,21 @@ _nis_getpwuid_r(void *nsrv, void *nscb,
_DIAGASSERT(result != NULL);
*result = NULL;
- memset(&state, 0, sizeof(state));
- rv = _nis_start(&state);
- if (rv != NS_SUCCESS)
- return rv;
snprintf(buffer, buflen, "%u", (unsigned int)uid);
- rv = _nis_pwscan(retval, pw, buffer, buflen,
- &state, PASSWD_BYUID(&state));
- _nis_end(&state);
+/* remark: we run under a global mutex inside of this module ... */
+ if (_nis_state.stayopen)
+ { /* use global state only if stayopen is set - otherwise we would blow up getpwent_r() ... */
+ rv = _nis_pwscan(retval, pw, buffer, buflen,
+ &_nis_state, __nis_pw_u_map);
+ }
+ else
+ { /* keep old semantic if no stayopen set - no need to call _nis_start() here - _nis_pwscan() will do it for us ... */
+ /* use same way as in getgrent.c ... */
+ memset(&state, 0, sizeof(state));
+ rv = _nis_pwscan(retval, pw, buffer, buflen,
+ &state, __nis_pw_u_map);
+ _nis_end(&state);
+ }
if (rv != NS_SUCCESS)
return rv;
if (uid == pw->pw_uid) {
@@ -1584,7 +1598,7 @@ _nis_getpwnam(void *nsrv, void *nscb, va
snprintf(_nis_passwdbuf, sizeof(_nis_passwdbuf), "%s", name);
rv = _nis_pwscan(&rerror, &_nis_passwd,
_nis_passwdbuf, sizeof(_nis_passwdbuf),
- &_nis_state, PASSWD_BYNAME(&_nis_state));
+ &_nis_state, __nis_pw_n_map);
if (!_nis_state.stayopen)
_nis_end(&_nis_state);
if (rv == NS_SUCCESS && strcmp(name, _nis_passwd.pw_name) == 0)
@@ -1613,13 +1627,20 @@ _nis_getpwnam_r(void *nsrv, void *nscb,
*result = NULL;
snprintf(buffer, buflen, "%s", name);
- memset(&state, 0, sizeof(state));
- rv = _nis_start(&state);
- if (rv != NS_SUCCESS)
- return rv;
- rv = _nis_pwscan(retval, pw, buffer, buflen,
- &state, PASSWD_BYNAME(&state));
- _nis_end(&state);
+/* remark: we run under a global mutex inside of this module ... */
+ if (_nis_state.stayopen)
+ { /* use global state only if stayopen is set - otherwise we would blow up getpwent_r() ... */
+ rv = _nis_pwscan(retval, pw, buffer, buflen,
+ &_nis_state, __nis_pw_n_map);
+ }
+ else
+ { /* keep old semantic if no stayopen set - no need to call _nis_start() here - _nis_pwscan() will do it for us ... */
+ /* use same way as in getgrent.c ... */
+ memset(&state, 0, sizeof(state));
+ rv = _nis_pwscan(retval, pw, buffer, buflen,
+ &state, __nis_pw_n_map);
+ _nis_end(&state);
+ }
if (rv != NS_SUCCESS)
return rv;
if (strcmp(name, pw->pw_name) == 0) {
@@ -2077,7 +2098,7 @@ _compat_pwscan(int *retval, struct passw
state->mode = COMPAT_FULL;
/* reset passwd_compat search */
/* XXXREENTRANT: setpassent is not thread safe ? */
- (void) _passwdcompat_setpassent(0);
+ (void) _passwdcompat_setpassent(_compat_state.stayopen);
break;
case '@': /* `+@netgroup' */
state->mode = COMPAT_NETGROUP;