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;

Reply via email to