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;