Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Jun 2001 18:05:09 +0300
From:      Ruslan Ermilov <ru@FreeBSD.org>
To:        arch@FreeBSD.org, current@FreeBSD.org
Subject:   ucred.cr_gid
Message-ID:  <20010622180509.D31008@sunbay.com>

next in thread | raw e-mail | index | archive | help

--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi!

The attached patch replaces ucred.cr_groups[0] with ucred.cr_gid.
This is mostly needed for POSIX alignment.  setegid(2) etc. should
not change supplementary groups set.

Also, type of <grp.h>'s group.gr_gid changed to a more natural
gid_t (also as in POSIX).

getgrouplist(3)'s and initgroups(3)'s prototypes fixed.
getgrouplist(3) has been also fixed to not duplicate the
primary group, and always return number of suplementary
groups, even if ngroups is zero (similar to sysctl(3)).

Assorted changes:

cmsgcred.cmcred_egid	New
kproc_info.ki_gid	New
portal_cred.pcr_gid	New
xucred.cr_gid		New

I'm not sure what to do with xucred.

Also, I'm not sure about KINFO_PROC_SIZE on ia64 and PowerPC.

Please review.

See also ChangeLog.


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age

--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=p

Index: include/grp.h
===================================================================
RCS file: /home/ncvs/src/include/grp.h,v
retrieving revision 1.3
diff -u -p -r1.3 grp.h
--- include/grp.h	1997/05/07 19:59:59	1.3
+++ include/grp.h	2001/06/22 14:50:40
@@ -48,7 +48,7 @@
 struct group {
 	char	*gr_name;		/* group name */
 	char	*gr_passwd;		/* group password */
-	int	gr_gid;			/* group id */
+	gid_t	gr_gid;			/* group id */
 	char	**gr_mem;		/* group members */
 };
 
Index: include/unistd.h
===================================================================
RCS file: /home/ncvs/src/include/unistd.h,v
retrieving revision 1.41
diff -u -p -r1.41 unistd.h
--- include/unistd.h	2001/05/27 19:57:36	1.41
+++ include/unistd.h	2001/06/22 14:50:40
@@ -138,7 +138,7 @@ int	 ftruncate __P((int, off_t));
 #endif
 int	 getdomainname __P((char *, int));
 int	 getdtablesize __P((void));
-int	 getgrouplist __P((const char *, int, int *, int *));
+int	 getgrouplist __P((const char *, gid_t, gid_t *, int *));
 long	 gethostid __P((void));
 int	 gethostname __P((char *, int));
 int	 getlogin_r __P((char *, int));
@@ -151,7 +151,7 @@ int	 getresuid __P((uid_t *, uid_t *, ui
 int	 getsid __P((pid_t _pid));
 char	*getusershell __P((void));
 char	*getwd __P((char *));			/* obsoleted by getcwd() */
-int	 initgroups __P((const char *, int));
+int	 initgroups __P((const char *, gid_t));
 int	 iruserok __P((unsigned long, int, const char *, const char *));
 int	 iruserok_sa __P((const void *, int, int, const char *, const char *));
 int	 issetugid __P((void));
Index: lib/libc/gen/getgrent.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getgrent.3,v
retrieving revision 1.15
diff -u -p -r1.15 getgrent.3
--- lib/libc/gen/getgrent.3	2000/11/20 16:18:45	1.15
+++ lib/libc/gen/getgrent.3	2001/06/22 14:50:41
@@ -78,7 +78,7 @@ file
 struct group {
 	char	*gr_name;	/* group name */
 	char	*gr_passwd;	/* group password */
-	int	gr_gid;		/* group id */
+	gid_t	gr_gid;		/* group id */
 	char	**gr_mem;	/* group members */
 };
 .Ed
Index: lib/libc/gen/getgrouplist.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getgrouplist.3,v
retrieving revision 1.6
diff -u -p -r1.6 getgrouplist.3
--- lib/libc/gen/getgrouplist.3	2000/10/30 13:23:18	1.6
+++ lib/libc/gen/getgrouplist.3	2001/06/22 14:50:41
@@ -43,18 +43,18 @@
 .Sh SYNOPSIS
 .Fd #include <unistd.h>
 .Ft int
-.Fn getgrouplist "const char *name" "int basegid" "int *groups" "int *ngroups"
+.Fn getgrouplist "const char *name" "gid_t basegid" "gid_t *groups" "int *ngroups"
 .Sh DESCRIPTION
 The
 .Fn getgrouplist
-function reads through the group file and calculates
+function reads through the group database and calculates
 the group access list for the user specified in
 .Fa name .
 The
 .Fa basegid
 is automatically included in the groups list.
 Typically this value is given as
-the group number from the password file.
+the group number from the password database.
 .Pp
 The resulting group list is returned in the integer array pointed to by
 .Fa groups .
@@ -64,6 +64,8 @@ array in the integer pointed to by
 .Fa ngroups ;
 the actual number of groups found is returned in
 .Fa ngroups .
+.Pp
+Duplicate group IDs will be suppressed from the result.
 .Sh RETURN VALUES
 The
 .Fn getgrouplist
@@ -94,3 +96,11 @@ If the invoking program uses any of thes
 the group structure will
 be overwritten in the call to
 .Fn getgrouplist .
+.Pp
+In the case where the group array is too small and duplicate GIDs
+have been suppressed, the returned
+.Fa ngroups
+will be too large by a factor of the difference between the given
+size and the number of matches.
+This is not considered to be a major problem, since it's still going
+to be a smaller figure than when duplicates were not suppressed.
Index: lib/libc/gen/getgrouplist.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/getgrouplist.c,v
retrieving revision 1.7
diff -u -p -r1.7 getgrouplist.c
--- lib/libc/gen/getgrouplist.c	1997/03/12 14:54:22	1.7
+++ lib/libc/gen/getgrouplist.c	2001/06/22 14:50:41
@@ -32,58 +32,66 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
+#if 0
 static char sccsid[] = "@(#)getgrouplist.c	8.2 (Berkeley) 12/8/94";
+#else
+static const char rcsid[] =
+  "$FreeBSD$";
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 /*
  * get credential
  */
-#include <sys/types.h>
-#include <string.h>
+#include <sys/param.h>
 #include <grp.h>
 
 int
 getgrouplist(uname, agroup, groups, grpcnt)
 	const char *uname;
-	int agroup;
-	register int *groups;
+	gid_t agroup;
+	gid_t *groups;
 	int *grpcnt;
 {
-	register struct group *grp;
-	register int i, ngroups;
+	struct group *grp;
+	int i, ngroups;
 	int ret, maxgroups;
 
 	ret = 0;
 	ngroups = 0;
 	maxgroups = *grpcnt;
+
 	/*
-	 * When installing primary group, duplicate it;
-	 * the first element of groups is the effective gid
-	 * and will be overwritten when a setgid file is executed.
+	 * Install primary group.
 	 */
-	groups[ngroups++] = agroup;
-	if (maxgroups > 1)
-		groups[ngroups++] = agroup;
+	if (ngroups < maxgroups)
+		groups[ngroups] = agroup;
+	else
+		ret = -1;
+	ngroups++;
+
 	/*
 	 * Scan the group file to find additional groups.
 	 */
 	setgrent();
-	while (grp = getgrent()) {
-		for (i = 0; i < ngroups; i++) {
-			if (grp->gr_gid == groups[i])
-				goto skip;
-		}
+nextgroup:
+	while ((grp = getgrent()) != NULL) {
+		if (grp->gr_gid == agroup)
+			continue;
 		for (i = 0; grp->gr_mem[i]; i++) {
 			if (!strcmp(grp->gr_mem[i], uname)) {
-				if (ngroups >= maxgroups) {
-					ret = -1;
-					break;
+				for (i = 0; i < MIN(ngroups, maxgroups); i++) {
+					if (grp->gr_gid == groups[i])
+						goto nextgroup;
 				}
-				groups[ngroups++] = grp->gr_gid;
+				if (ngroups < maxgroups)
+					groups[ngroups] = grp->gr_gid;
+				else
+					ret = -1;
+				ngroups++;
 				break;
 			}
 		}
-skip:
 	}
 	endgrent();
 	*grpcnt = ngroups;
Index: lib/libc/gen/initgroups.3
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/initgroups.3,v
retrieving revision 1.8
diff -u -p -r1.8 initgroups.3
--- lib/libc/gen/initgroups.3	2000/10/30 13:23:18	1.8
+++ lib/libc/gen/initgroups.3	2001/06/22 14:50:41
@@ -32,9 +32,9 @@
 .\"     @(#)initgroups.3	8.1 (Berkeley) 6/4/93
 .\" $FreeBSD: src/lib/libc/gen/initgroups.3,v 1.8 2000/10/30 13:23:18 asmodai Exp $
 .\"
-.Dd June 4, 1993
+.Dd June 21, 2001
 .Dt INITGROUPS 3
-.Os BSD 4.2
+.Os
 .Sh NAME
 .Nm initgroups
 .Nd initialize group access list
@@ -43,7 +43,7 @@
 .Sh SYNOPSIS
 .Fd #include <unistd.h>
 .Ft int
-.Fn initgroups "const char *name" "int basegid"
+.Fn initgroups "const char *name" "gid_t basegid"
 .Sh DESCRIPTION
 The
 .Fn initgroups
Index: lib/libc/gen/initgroups.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/gen/initgroups.c,v
retrieving revision 1.3
diff -u -p -r1.3 initgroups.c
--- lib/libc/gen/initgroups.c	1996/07/12 18:53:56	1.3
+++ lib/libc/gen/initgroups.c	2001/06/22 14:50:41
@@ -32,27 +32,33 @@
  */
 
 #if defined(LIBC_SCCS) && !defined(lint)
+#if 0
 static char sccsid[] = "@(#)initgroups.c	8.1 (Berkeley) 6/4/93";
+#else
+static const char rcsid[] =
+  "$FreeBSD$";
+#endif
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
 
-#include <stdio.h>
 #include <err.h>
+#include <stdio.h>
 #include <unistd.h>
 
 int
 initgroups(uname, agroup)
 	const char *uname;
-	int agroup;
+	gid_t agroup;
 {
-	int groups[NGROUPS], ngroups;
+	int ngroups;
+	gid_t groups[NGROUPS];
 
 	ngroups = NGROUPS;
 	if (getgrouplist(uname, agroup, groups, &ngroups) < 0)
 		warnx("%s is in too many groups, using first %d",
 		    uname, ngroups);
-	if (setgroups(ngroups, groups) < 0) {
+	if (setgroups(ngroups, groups) == -1) {
 		warn("setgroups");
 		return (-1);
 	}
Index: lib/libc/sys/recv.2
===================================================================
RCS file: /home/ncvs/src/lib/libc/sys/recv.2,v
retrieving revision 1.12
diff -u -p -r1.12 recv.2
--- lib/libc/sys/recv.2	2001/02/01 16:29:44	1.12
+++ lib/libc/sys/recv.2	2001/06/22 14:50:41
@@ -225,6 +225,7 @@ struct cmsgcred {
 	uid_t	cmcred_uid;		/* real UID of sending process */
 	uid_t	cmcred_euid;		/* effective UID of sending process */
 	gid_t	cmcred_gid;		/* real GID of sending process */
+	gid_t	cmcred_egid;		/* effective GID of sending process */
 	short	cmcred_ngroups;		/* number or groups */
 	gid_t	cmcred_groups[CMGROUP_MAX];	/* groups */
 };
Index: lib/libkvm/kvm_proc.c
===================================================================
RCS file: /home/ncvs/src/lib/libkvm/kvm_proc.c,v
retrieving revision 1.36
diff -u -p -r1.36 kvm_proc.c
--- lib/libkvm/kvm_proc.c	2001/05/25 16:58:46	1.36
+++ lib/libkvm/kvm_proc.c	2001/06/22 14:50:41
@@ -135,6 +135,7 @@ kvm_proclist(kd, what, arg, p, bp, maxcn
 			bcopy(ucred.cr_groups, kp->ki_groups,
 			    NGROUPS * sizeof(gid_t));
 			kp->ki_uid = ucred.cr_uid;
+			kp->ki_gid = ucred.cr_gid;
 		}
 
 		switch(what) {
Index: sbin/mount_portalfs/pt_file.c
===================================================================
RCS file: /home/ncvs/src/sbin/mount_portalfs/pt_file.c,v
retrieving revision 1.8
diff -u -p -r1.8 pt_file.c
--- sbin/mount_portalfs/pt_file.c	1999/08/28 00:13:38	1.8
+++ sbin/mount_portalfs/pt_file.c	2001/06/22 14:50:41
@@ -69,7 +69,7 @@ int *fdp;
 	strcpy(pbuf+1, key + (v[1] ? strlen(v[1]) : 0));
 
 #ifdef DEBUG
-	printf("path = %s, uid = %d, gid = %d\n", pbuf, pcr->pcr_uid, pcr->pcr_groups[0]);
+	printf("path = %s, uid = %d, gid = %d\n", pbuf, pcr->pcr_uid, pcr->pcr_gid);
 	printf ("fflag = %x, oflag = %x\n", pcr->pcr_flag, (pcr->pcr_flag)-1);
 #endif
 
@@ -80,6 +80,9 @@ int *fdp;
 		return (errno);
 
 	if (seteuid(pcr->pcr_uid) < 0)
+		return (errno);
+
+	if (setegid(pcr->pcr_gid) < 0)
 		return (errno);
 
 	/* dmb convert kernel flags to oflags, see <fcntl.h> */
Index: sbin/mountd/mountd.c
===================================================================
RCS file: /home/ncvs/src/sbin/mountd/mountd.c,v
retrieving revision 1.55
diff -u -p -r1.55 mountd.c
--- sbin/mountd/mountd.c	2001/06/01 10:57:24	1.55
+++ sbin/mountd/mountd.c	2001/06/22 14:50:41
@@ -214,9 +214,9 @@ char exname[MAXPATHLEN];
 struct xucred def_anon = {
 	0,
 	(uid_t)-2,
-	1,
-	{ (gid_t)-2 },
-	NULL
+	(gid_t)-2,
+	0,
+	{ (gid_t)0 }
 };
 int force_v2 = 0;
 int resvport_only = 1;
@@ -2072,8 +2072,8 @@ parsecred(namelist, cr)
 	 * Set up the unprivileged user.
 	 */
 	cr->cr_uid = -2;
-	cr->cr_groups[0] = -2;
-	cr->cr_ngroups = 1;
+	cr->cr_gid = -2;
+	cr->cr_ngroups = 0;
 	/*
 	 * Get the user's password table entry.
 	 */
@@ -2098,9 +2098,9 @@ parsecred(namelist, cr)
 		/*
 		 * Convert from int's to gid_t's and compress out duplicate
 		 */
+		cr->cr_gid = groups[0];
 		cr->cr_ngroups = ngroups - 1;
-		cr->cr_groups[0] = groups[0];
-		for (cnt = 2; cnt < ngroups; cnt++)
+		for (cnt = 1; cnt < ngroups; cnt++)
 			cr->cr_groups[cnt - 1] = groups[cnt];
 		return;
 	}
Index: sbin/nfsd/nfsd.c
===================================================================
RCS file: /home/ncvs/src/sbin/nfsd/nfsd.c,v
retrieving revision 1.19
diff -u -p -r1.19 nfsd.c
--- sbin/nfsd/nfsd.c	2001/03/25 23:32:55	1.19
+++ sbin/nfsd/nfsd.c	2001/06/22 14:50:45
@@ -433,11 +433,11 @@ main(argc, argv, envp)
 				(pwd = getpwnam(lnam)) != NULL) {
 				cr = &nsd.nsd_cr;
 				cr->cr_uid = pwd->pw_uid;
-				cr->cr_groups[0] = pwd->pw_gid;
-				cr->cr_ngroups = 1;
+				cr->cr_gid = pwd->pw_gid;
+				cr->cr_ngroups = 0;
 				setgrent();
 				while ((grp = getgrent()) != NULL) {
-					if (grp->gr_gid == cr->cr_groups[0])
+					if (grp->gr_gid == cr->cr_gid)
 						continue;
 					for (cpp = grp->gr_mem;
 					    *cpp != NULL; ++cpp)
Index: sys/alpha/osf1/osf1_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/alpha/osf1/osf1_misc.c,v
retrieving revision 1.16
diff -u -p -r1.16 osf1_misc.c
--- sys/alpha/osf1/osf1_misc.c	2001/06/06 14:07:52	1.16
+++ sys/alpha/osf1/osf1_misc.c	2001/06/22 14:50:45
@@ -1119,7 +1119,7 @@ osf1_setgid(p, uap)
 			setsugid(p);
 		}
 	}
-	if (newcred->cr_groups[0] != gid) {
+	if (newcred->cr_gid != gid) {
 		change_egid(newcred, gid);
 		setsugid(p);
 	}
Index: sys/coda/coda_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/coda/coda_vnops.c,v
retrieving revision 1.34
diff -u -p -r1.34 coda_vnops.c
--- sys/coda/coda_vnops.c	2001/06/14 09:28:30	1.34
+++ sys/coda/coda_vnops.c	2001/06/22 14:50:47
@@ -1928,7 +1928,8 @@ print_cred(cred)
 
 	int i;
 
-	myprintf(("ref %d\tuid %d\n",cred->cr_ref,cred->cr_uid));
+	myprintf(("ref %d\tuid %d\tgid %d\n",cred->cr_ref,cred->cr_uid,
+	    cred->cr_gid));
 
 	for (i=0; i < cred->cr_ngroups; i++)
 		myprintf(("\tgroup %d: (%d)\n",i,cred->cr_groups[i]));
Index: sys/compat/linux/linux_misc.c
===================================================================
RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v
retrieving revision 1.103
diff -u -p -r1.103 linux_misc.c
--- sys/compat/linux/linux_misc.c	2001/06/15 07:46:18	1.103
+++ sys/compat/linux/linux_misc.c	2001/06/22 14:50:47
@@ -966,16 +966,10 @@ linux_setgroups(p, uap)
 	ngrp = uap->gidsetsize;
 	oldcred = p->p_ucred;
 
-	/*
-	 * cr_groups[0] holds egid. Setting the whole set from
-	 * the supplied set will cause egid to be changed too.
-	 * Keep cr_groups[0] unchanged to prevent that.
-	 */
-
 	if ((error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
 		return (error);
 
-	if (ngrp >= NGROUPS)
+	if (ngrp > NGROUPS)
 		return (EINVAL);
 
 	newcred = crdup(oldcred);
@@ -985,17 +979,16 @@ linux_setgroups(p, uap)
 		if (error)
 			return (error);
 
-		newcred->cr_ngroups = ngrp + 1;
+		newcred->cr_ngroups = ngrp;
 
 		bsd_gidset = newcred->cr_groups;
-		ngrp--;
 		while (ngrp >= 0) {
-			bsd_gidset[ngrp + 1] = linux_gidset[ngrp];
+			bsd_gidset[ngrp] = linux_gidset[ngrp];
 			ngrp--;
 		}
 	}
 	else
-		newcred->cr_ngroups = 1;
+		newcred->cr_ngroups = 0;
 
 	setsugid(p);
 	p->p_ucred = newcred;
@@ -1015,13 +1008,7 @@ linux_getgroups(p, uap)
 
 	cred = p->p_ucred;
 	bsd_gidset = cred->cr_groups;
-	bsd_gidsetsz = cred->cr_ngroups - 1;
-
-	/*
-	 * cr_groups[0] holds egid. Returning the whole set
-	 * here will cause a duplicate. Exclude cr_groups[0]
-	 * to prevent that.
-	 */
+	bsd_gidsetsz = cred->cr_ngroups;
 
 	if ((ngrp = uap->gidsetsize) == 0) {
 		p->p_retval[0] = bsd_gidsetsz;
@@ -1033,7 +1020,7 @@ linux_getgroups(p, uap)
 
 	ngrp = 0;
 	while (ngrp < bsd_gidsetsz) {
-		linux_gidset[ngrp] = bsd_gidset[ngrp + 1];
+		linux_gidset[ngrp] = bsd_gidset[ngrp];
 		ngrp++;
 	}
 
Index: sys/fs/portalfs/portal.h
===================================================================
RCS file: /home/ncvs/src/sys/fs/portalfs/portal.h,v
retrieving revision 1.7
diff -u -p -r1.7 portal.h
--- sys/fs/portalfs/portal.h	1999/12/29 04:54:45	1.7
+++ sys/fs/portalfs/portal.h	2001/06/22 14:50:47
@@ -46,6 +46,7 @@ struct portal_args {
 struct portal_cred {
 	int		pcr_flag;		/* File open mode */
 	uid_t		pcr_uid;		/* From ucred */
+	gid_t		pcr_gid;		/* From ucred */
 	short		pcr_ngroups;		/* From ucred */
 	gid_t		pcr_groups[NGROUPS];	/* From ucred */
 };
Index: sys/fs/portalfs/portal_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/portalfs/portal_vnops.c,v
retrieving revision 1.42
diff -u -p -r1.42 portal_vnops.c
--- sys/fs/portalfs/portal_vnops.c	2001/06/15 00:38:03	1.42
+++ sys/fs/portalfs/portal_vnops.c	2001/06/22 14:50:48
@@ -305,6 +305,7 @@ portal_open(ap)
 
 	pcred.pcr_flag = ap->a_mode;
 	pcred.pcr_uid = ap->a_cred->cr_uid;
+	pcred.pcr_gid = ap->a_cred->cr_gid;
 	pcred.pcr_ngroups = ap->a_cred->cr_ngroups;
 	bcopy(ap->a_cred->cr_groups, pcred.pcr_groups, NGROUPS * sizeof(gid_t));
 	aiov[0].iov_base = (caddr_t) &pcred;
Index: sys/fs/procfs/procfs_mem.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_mem.c,v
retrieving revision 1.50
diff -u -p -r1.50 procfs_mem.c
--- sys/fs/procfs/procfs_mem.c	2001/05/23 09:42:11	1.50
+++ sys/fs/procfs/procfs_mem.c	2001/06/22 14:50:49
@@ -312,7 +312,6 @@ procfs_findtextvp(p)
 int procfs_kmemaccess(curp)
 	struct proc *curp;
 {
-	int i;
 	struct ucred *cred;
 
 	cred = curp->p_ucred;
@@ -320,9 +319,5 @@ int procfs_kmemaccess(curp)
 		return 1;
 
 	/* XXX: Why isn't this done with file-perms ??? */
-	for (i = 0; i < cred->cr_ngroups; i++)
-		if (cred->cr_groups[i] == KMEM_GROUP)	
-			return 1;
-	
-	return 0;
+	return (groupmember((gid_t)KMEM_GROUP, cred));
 }
Index: sys/fs/procfs/procfs_status.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_status.c,v
retrieving revision 1.31
diff -u -p -r1.31 procfs_status.c
--- sys/fs/procfs/procfs_status.c	2001/05/25 16:59:04	1.31
+++ sys/fs/procfs/procfs_status.c	2001/06/22 14:50:49
@@ -157,9 +157,9 @@ procfs_dostatus(curp, p, pfs, uio)
 		(u_long)cr->cr_rgid);
 	DOCHECK();
 
-	/* egid (cr->cr_svgid) is equal to cr_ngroups[0] 
-	   see also getegid(2) in /sys/kern/kern_prot.c */
-
+	ps += snprintf(ps, psbuf + sizeof(psbuf) - ps,
+	    ",%lu", (u_long)cr->cr_gid);
+	DOCHECK();
 	for (i = 0; i < cr->cr_ngroups; i++) {
 		ps += snprintf(ps, psbuf + sizeof(psbuf) - ps,
 		    ",%lu", (u_long)cr->cr_groups[i]);
Index: sys/fs/umapfs/umap_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/umapfs/umap_subr.c,v
retrieving revision 1.25
diff -u -p -r1.25 umap_subr.c
--- sys/fs/umapfs/umap_subr.c	2001/05/23 09:42:13	1.25
+++ sys/fs/umapfs/umap_subr.c	2001/06/22 14:50:49
@@ -373,9 +373,6 @@ umap_mapids(v_mount, credp)
 	else
 		credp->cr_uid = (uid_t) NOBODY;
 
-#ifdef notdef
-	/* cr_gid is the same as cr_groups[0] in 4BSD */
-
 	/* Find gid entry in map */
 
 	gid = (gid_t) umap_findid(credp->cr_gid,
@@ -386,7 +383,6 @@ umap_mapids(v_mount, credp)
 		credp->cr_gid = gid;
 	else
 		credp->cr_gid = NULLGROUP;
-#endif
 
 	/* Now we must map each of the set of groups in the cr_groups
 		structure. */
Index: sys/gnu/ext2fs/ext2_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/gnu/ext2fs/ext2_vnops.c,v
retrieving revision 1.56
diff -u -p -r1.56 ext2_vnops.c
--- sys/gnu/ext2fs/ext2_vnops.c	2001/05/01 08:34:27	1.56
+++ sys/gnu/ext2fs/ext2_vnops.c	2001/06/22 14:50:49
@@ -855,8 +855,8 @@ ext2_mkdir(ap)
 				 */
 				ucred.cr_ref = 1;
 				ucred.cr_uid = ip->i_uid;
-				ucred.cr_ngroups = 1;
-				ucred.cr_groups[0] = dp->i_gid;
+				ucred.cr_ngroups = 0;
+				ucred.cr_gid = dp->i_gid;
 				ucp = &ucred;
 			}
 #endif			I
@@ -1120,8 +1120,8 @@ ext2_makeinode(mode, dvp, vpp, cnp)
 			 */
 			ucred.cr_ref = 1;
 			ucred.cr_uid = ip->i_uid;
-			ucred.cr_ngroups = 1;
-			ucred.cr_groups[0] = pdir->i_gid;
+			ucred.cr_ngroups = 0;
+			ucred.cr_gid = pdir->i_gid;
 			ucp = &ucred;
 #endif			I
 		} else {
Index: sys/kern/kern_proc.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_proc.c,v
retrieving revision 1.95
diff -u -p -r1.95 kern_proc.c
--- sys/kern/kern_proc.c	2001/06/20 23:10:06	1.95
+++ sys/kern/kern_proc.c	2001/06/22 14:50:50
@@ -431,6 +431,7 @@ fill_kinfo_proc(p, kp)
 		kp->ki_ngroups = p->p_ucred->cr_ngroups;
 		bcopy(p->p_ucred->cr_groups, kp->ki_groups,
 		    NGROUPS * sizeof(gid_t));
+		kp->ki_gid = p->p_ucred->cr_gid;
 		kp->ki_rgid = p->p_ucred->cr_rgid;
 		kp->ki_svgid = p->p_ucred->cr_svgid;
 	}
Index: sys/kern/kern_prot.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_prot.c,v
retrieving revision 1.93
diff -u -p -r1.93 kern_prot.c
--- sys/kern/kern_prot.c	2001/06/06 13:58:03	1.93
+++ sys/kern/kern_prot.c	2001/06/22 14:50:50
@@ -255,15 +255,13 @@ getgid(p, uap)
 
 	p->p_retval[0] = p->p_ucred->cr_rgid;
 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
-	p->p_retval[1] = p->p_ucred->cr_groups[0];
+	p->p_retval[1] = p->p_ucred->cr_gid;
 #endif
 	return (0);
 }
 
 /*
- * Get effective group ID.  The "egid" is groups[0], and could be obtained
- * via getgroups.  This syscall exists because it is somewhat painful to do
- * correctly in a library function.
+ * Get effective group ID.
  */
 #ifndef _SYS_SYSPROTO_H_
 struct getegid_args {
@@ -278,7 +276,7 @@ getegid(p, uap)
 	struct getegid_args *uap;
 {
 
-	p->p_retval[0] = p->p_ucred->cr_groups[0];
+	p->p_retval[0] = p->p_ucred->cr_gid;
 	return (0);
 }
 
@@ -574,7 +572,7 @@ setgid(p, uap)
 	    gid != oldcred->cr_svgid &&		/* allow setgid(saved gid) */
 #endif
 #ifdef POSIX_APPENDIX_B_4_2_2	/* Use BSD-compat clause from B.4.2.2 */
-	    gid != oldcred->cr_groups[0] && /* allow setgid(getegid()) */
+	    gid != oldcred->cr_gid && /* allow setgid(getegid()) */
 #endif
 	    (error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
 		return (error);
@@ -587,7 +585,7 @@ setgid(p, uap)
 	 */
 	if (
 #ifdef POSIX_APPENDIX_B_4_2_2	/* use the clause from B.4.2.2 */
-	    gid == oldcred->cr_groups[0] ||
+	    gid == oldcred->cr_gid ||
 #endif
 	    suser_xxx(oldcred, NULL, PRISON_ROOT) == 0) /* we are using privs */
 #endif
@@ -615,7 +613,7 @@ setgid(p, uap)
 	 * In all cases permitted cases, we are changing the egid.
 	 * Copy credentials so other references do not see our changes.
 	 */
-	if (oldcred->cr_groups[0] != gid) {
+	if (oldcred->cr_gid != gid) {
 		change_egid(newcred, gid);
 		setsugid(p);
 	}
@@ -646,7 +644,7 @@ setegid(p, uap)
 	    (error = suser_xxx(oldcred, NULL, PRISON_ROOT)))
 		return (error);
 	newcred = crdup(oldcred);
-	if (oldcred->cr_groups[0] != egid) {
+	if (oldcred->cr_gid != egid) {
 		change_egid(newcred, egid);
 		setsugid(p);
 	}
@@ -769,13 +767,13 @@ setregid(p, uap)
 	oldcred = p->p_ucred;
 	if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
 	    rgid != oldcred->cr_svgid) ||
-	     (egid != (gid_t)-1 && egid != oldcred->cr_groups[0] &&
+	     (egid != (gid_t)-1 && egid != oldcred->cr_gid &&
 	     egid != oldcred->cr_rgid && egid != oldcred->cr_svgid)) &&
 	    (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
 		return (error);
 
 	newcred = crdup(oldcred);
-	if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
+	if (egid != (gid_t)-1 && oldcred->cr_gid != egid) {
 		change_egid(newcred, egid);
 		setsugid(p);
 	}
@@ -783,9 +781,9 @@ setregid(p, uap)
 		change_rgid(newcred, rgid);
 		setsugid(p);
 	}
-	if ((rgid != (gid_t)-1 || newcred->cr_groups[0] != newcred->cr_rgid) &&
-	    newcred->cr_svgid != newcred->cr_groups[0]) {
-		change_svgid(newcred, newcred->cr_groups[0]);
+	if ((rgid != (gid_t)-1 || newcred->cr_gid != newcred->cr_rgid) &&
+	    newcred->cr_svgid != newcred->cr_gid) {
+		change_svgid(newcred, newcred->cr_gid);
 		setsugid(p);
 	}
 	p->p_ucred = newcred;
@@ -877,18 +875,18 @@ setresgid(p, uap)
 	oldcred = p->p_ucred;
 	if (((rgid != (gid_t)-1 && rgid != oldcred->cr_rgid &&
 	      rgid != oldcred->cr_svgid &&
-	      rgid != oldcred->cr_groups[0]) ||
+	      rgid != oldcred->cr_gid) ||
 	     (egid != (gid_t)-1 && egid != oldcred->cr_rgid &&
 	      egid != oldcred->cr_svgid &&
-	      egid != oldcred->cr_groups[0]) ||
+	      egid != oldcred->cr_gid) ||
 	     (sgid != (gid_t)-1 && sgid != oldcred->cr_rgid &&
 	      sgid != oldcred->cr_svgid &&
-	      sgid != oldcred->cr_groups[0])) &&
+	      sgid != oldcred->cr_gid)) &&
 	    (error = suser_xxx(oldcred, NULL, PRISON_ROOT)) != 0)
 		return (error);
 
 	newcred = crdup(oldcred);
-	if (egid != (gid_t)-1 && oldcred->cr_groups[0] != egid) {
+	if (egid != (gid_t)-1 && oldcred->cr_gid != egid) {
 		change_egid(newcred, egid);
 		setsugid(p);
 	}
@@ -953,8 +951,8 @@ getresgid(p, uap)
 		error1 = copyout((caddr_t)&cred->cr_rgid,
 		    (caddr_t)uap->rgid, sizeof(cred->cr_rgid));
 	if (uap->egid)
-		error2 = copyout((caddr_t)&cred->cr_groups[0],
-		    (caddr_t)uap->egid, sizeof(cred->cr_groups[0]));
+		error2 = copyout((caddr_t)&cred->cr_gid,
+		    (caddr_t)uap->egid, sizeof(cred->cr_gid));
 	if (uap->sgid)
 		error3 = copyout((caddr_t)&cred->cr_svgid,
 		    (caddr_t)uap->sgid, sizeof(cred->cr_svgid));
@@ -1018,6 +1016,8 @@ groupmember(gid, cred)
 	register gid_t *gp;
 	gid_t *egp;
 
+	if (cred->cr_gid == gid)
+		return (1);
 	egp = &(cred->cr_groups[cred->cr_ngroups]);
 	for (gp = cred->cr_groups; gp < egp; gp++)
 		if (*gp == gid)
@@ -1447,7 +1447,7 @@ change_egid(newcred, egid)
 	gid_t egid;
 {
 
-	newcred->cr_groups[0] = egid;
+	newcred->cr_gid = egid;
 }
 
 /*
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.66
diff -u -p -r1.66 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c	2001/05/25 16:59:07	1.66
+++ sys/kern/uipc_usrreq.c	2001/06/22 14:50:50
@@ -991,6 +991,7 @@ unp_internalize(control, p)
 		cmcred->cmcred_uid = p->p_ucred->cr_ruid;
 		cmcred->cmcred_gid = p->p_ucred->cr_rgid;
 		cmcred->cmcred_euid = p->p_ucred->cr_uid;
+		cmcred->cmcred_egid = p->p_ucred->cr_gid;
 		cmcred->cmcred_ngroups = MIN(p->p_ucred->cr_ngroups,
 							CMGROUP_MAX);
 		for (i = 0; i < cmcred->cmcred_ngroups; i++)
Index: sys/kern/vfs_aio.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_aio.c,v
retrieving revision 1.98
diff -u -p -r1.98 vfs_aio.c
--- sys/kern/vfs_aio.c	2001/04/18 22:18:39	1.98
+++ sys/kern/vfs_aio.c	2001/06/22 14:50:51
@@ -694,8 +694,8 @@ aio_daemon(void *uproc)
 	mycp->p_ucred->cr_uid = 0;
 	uifree(mycp->p_ucred->cr_uidinfo);
 	mycp->p_ucred->cr_uidinfo = uifind(0);
-	mycp->p_ucred->cr_ngroups = 1;
-	mycp->p_ucred->cr_groups[0] = 1;
+	mycp->p_ucred->cr_ngroups = 0;
+	mycp->p_ucred->cr_gid = 1;
 
 	/* The daemon resides in its own pgrp. */
 	enterpgrp(mycp, mycp->p_pid, 1);
Index: sys/kern/vfs_export.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_export.c,v
retrieving revision 1.311
diff -u -p -r1.311 vfs_export.c
--- sys/kern/vfs_export.c	2001/05/29 17:46:52	1.311
+++ sys/kern/vfs_export.c	2001/06/22 14:50:51
@@ -99,6 +99,7 @@ vfs_hang_addrlist(mp, nep, argp)
 		np->netc_exflags = argp->ex_flags;
 		bzero(&np->netc_anon, sizeof(np->netc_anon));
 		np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
+		np->netc_anon.cr_gid = argp->ex_anon.cr_gid;
 		np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
 		bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
 		    sizeof(np->netc_anon.cr_groups));
@@ -147,6 +148,7 @@ vfs_hang_addrlist(mp, nep, argp)
 	np->netc_exflags = argp->ex_flags;
 	bzero(&np->netc_anon, sizeof(np->netc_anon));
 	np->netc_anon.cr_uid = argp->ex_anon.cr_uid;
+	np->netc_anon.cr_gid = argp->ex_anon.cr_gid;
 	np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups;
 	bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups,
 	    sizeof(np->netc_anon.cr_groups));
Index: sys/kern/vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.194
diff -u -p -r1.194 vfs_syscalls.c
--- sys/kern/vfs_syscalls.c	2001/06/06 23:34:38	1.194
+++ sys/kern/vfs_syscalls.c	2001/06/22 14:50:53
@@ -1711,7 +1711,7 @@ access(p, uap)
 	 */
 	tmpcred = crdup(cred);
 	tmpcred->cr_uid = cred->cr_ruid;
-	tmpcred->cr_groups[0] = cred->cr_rgid;
+	tmpcred->cr_gid = cred->cr_rgid;
 	p->p_ucred = tmpcred;
 	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | NOOBJ, UIO_USERSPACE,
 	    SCARG(uap, path), p);
Index: sys/netinet/tcp_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.105
diff -u -p -r1.105 tcp_subr.c
--- sys/netinet/tcp_subr.c	2001/06/20 12:32:48	1.105
+++ sys/netinet/tcp_subr.c	2001/06/22 14:50:53
@@ -898,6 +898,7 @@ tcp_getcred(SYSCTL_HANDLER_ARGS)
 	}
 	bzero(&xuc, sizeof(xuc));
 	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_gid = inp->inp_socket->so_cred->cr_gid;
 	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
 	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
 	    sizeof(xuc.cr_groups));
@@ -950,6 +951,7 @@ tcp6_getcred(SYSCTL_HANDLER_ARGS)
 	}
 	bzero(&xuc, sizeof(xuc));
 	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_gid = inp->inp_socket->so_cred->cr_gid;
 	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
 	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
 	    sizeof(xuc.cr_groups));
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.90
diff -u -p -r1.90 udp_usrreq.c
--- sys/netinet/udp_usrreq.c	2001/06/11 19:48:18	1.90
+++ sys/netinet/udp_usrreq.c	2001/06/22 14:50:55
@@ -643,6 +643,7 @@ udp_getcred(SYSCTL_HANDLER_ARGS)
 	}
 	bzero(&xuc, sizeof(xuc));
 	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_gid = inp->inp_socket->so_cred->cr_gid;
 	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
 	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
 	    sizeof(xuc.cr_groups));
Index: sys/netinet6/udp6_usrreq.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet6/udp6_usrreq.c,v
retrieving revision 1.15
diff -u -p -r1.15 udp6_usrreq.c
--- sys/netinet6/udp6_usrreq.c	2001/06/11 12:39:06	1.15
+++ sys/netinet6/udp6_usrreq.c	2001/06/22 14:50:57
@@ -493,6 +493,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
 	}
 	bzero(&xuc, sizeof(xuc));
 	xuc.cr_uid = inp->inp_socket->so_cred->cr_uid;
+	xuc.cr_gid = inp->inp_socket->so_cred->cr_gid;
 	xuc.cr_ngroups = inp->inp_socket->so_cred->cr_ngroups;
 	bcopy(inp->inp_socket->so_cred->cr_groups, xuc.cr_groups,
 	    sizeof(xuc.cr_groups));
Index: sys/netncp/ncp_conn.c
===================================================================
RCS file: /home/ncvs/src/sys/netncp/ncp_conn.c,v
retrieving revision 1.16
diff -u -p -r1.16 ncp_conn.c
--- sys/netncp/ncp_conn.c	2001/06/13 10:58:37	1.16
+++ sys/netncp/ncp_conn.c	2001/06/22 14:50:57
@@ -245,7 +245,7 @@ ncp_conn_alloc(struct ncp_conn_args *cap
 	ncp->connid = 0xFFFF;
 	ncp->li = *cap;
 	ncp->nc_group = (cap->group != NCP_DEFAULT_GROUP) ? 
-		cap->group : cred->cr_groups[0];
+		cap->group : cred->cr_gid;
 
 	if (cap->retry_count == 0)
 		ncp->li.retry_count = NCP_RETRY_COUNT;
Index: sys/netsmb/smb_conn.c
===================================================================
RCS file: /home/ncvs/src/sys/netsmb/smb_conn.c,v
retrieving revision 1.2
diff -u -p -r1.2 smb_conn.c
--- sys/netsmb/smb_conn.c	2001/06/13 10:58:38	1.2
+++ sys/netsmb/smb_conn.c	2001/06/22 14:50:57
@@ -407,7 +407,7 @@ smb_vc_create(struct smb_vcspec *vcspec,
 	if (uid == SMBM_ANY_OWNER)
 		uid = realuid;
 	if (gid == SMBM_ANY_GROUP)
-		gid = cred->cr_groups[0];
+		gid = cred->cr_gid;
 	vcp->vc_uid = uid;
 	vcp->vc_grp = gid;
 
@@ -689,7 +689,7 @@ smb_share_create(struct smb_vc *vcp, str
 	if (uid == SMBM_ANY_OWNER)
 		uid = realuid;
 	if (gid == SMBM_ANY_GROUP)
-		gid = cred->cr_groups[0];
+		gid = cred->cr_gid;
 	ssp = smb_zmalloc(sizeof(*ssp), M_SMBCONN, M_WAITOK);
 	smb_co_init(SSTOCP(ssp), SMBL_SHARE, "smbss", p);
 	ssp->obj.co_free = smb_share_free;
Index: sys/nfs/nfs_socket.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_socket.c,v
retrieving revision 1.66
diff -u -p -r1.66 nfs_socket.c
--- sys/nfs/nfs_socket.c	2001/05/01 08:13:14	1.66
+++ sys/nfs/nfs_socket.c	2001/06/22 14:50:58
@@ -1824,12 +1824,12 @@ nfs_getreq(nd, nfsd, has_header)
 			return (EBADRPC);
 		}
 		nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED);
-		for (i = 1; i <= len; i++)
+		for (i = 0; i < len; i++)
 		    if (i < NGROUPS)
 			nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
 		    else
 			tl++;
-		nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
+		nd->nd_cr.cr_ngroups = (len > NGROUPS) ? NGROUPS : len;
 		if (nd->nd_cr.cr_ngroups > 1)
 		    nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
 		len = fxdr_unsigned(int, *++tl);
Index: sys/nfs/nfs_subs.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_subs.c,v
retrieving revision 1.101
diff -u -p -r1.101 nfs_subs.c
--- sys/nfs/nfs_subs.c	2001/05/19 01:28:07	1.101
+++ sys/nfs/nfs_subs.c	2001/06/22 14:51:00
@@ -701,10 +701,10 @@ nfsm_rpchead(cr, nmflag, procid, auth_ty
 		*tl++ = 0;		/* stamp ?? */
 		*tl++ = 0;		/* NULL hostname */
 		*tl++ = txdr_unsigned(cr->cr_uid);
-		*tl++ = txdr_unsigned(cr->cr_groups[0]);
+		*tl++ = txdr_unsigned(cr->cr_gid);
 		grpsiz = (auth_len >> 2) - 5;
 		*tl++ = txdr_unsigned(grpsiz);
-		for (i = 1; i <= grpsiz; i++)
+		for (i = 0; i < grpsiz; i++)
 			*tl++ = txdr_unsigned(cr->cr_groups[i]);
 		break;
 	case RPCAUTH_KERB4:
@@ -1976,6 +1976,7 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, s
 		return (NFSERR_AUTHERR | AUTH_TOOWEAK);
 	} else if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) {
 		cred->cr_uid = credanon->cr_uid;
+		cred->cr_gid = credanon->cr_gid;
 		for (i = 0; i < credanon->cr_ngroups && i < NGROUPS; i++)
 			cred->cr_groups[i] = credanon->cr_groups[i];
 		cred->cr_ngroups = i;
@@ -2233,6 +2234,7 @@ nfsrv_setcred(incred, outcred)
 	bzero((caddr_t)outcred, sizeof (struct ucred));
 	outcred->cr_ref = 1;
 	outcred->cr_uid = incred->cr_uid;
+	outcred->cr_gid = incred->cr_gid;
 	outcred->cr_ngroups = incred->cr_ngroups;
 	for (i = 0; i < incred->cr_ngroups; i++)
 		outcred->cr_groups[i] = incred->cr_groups[i];
Index: sys/nfs/nfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_syscalls.c,v
retrieving revision 1.68
diff -u -p -r1.68 nfs_syscalls.c
--- sys/nfs/nfs_syscalls.c	2001/04/29 02:45:08	1.68
+++ sys/nfs/nfs_syscalls.c	2001/06/22 14:51:01
@@ -271,6 +271,7 @@ nfssvc(p, uap)
 				nuidp->nu_flag = 0;
 				bzero(&nuidp->nu_cr, sizeof(nuidp->nu_cr));
 				nuidp->nu_cr.cr_uid = nsd->nsd_cr.cr_uid;
+				nuidp->nu_cr.cr_gid = nsd->nsd_cr.cr_gid;
 				nuidp->nu_cr.cr_ngroups =
 				  nsd->nsd_cr.cr_ngroups;
 				bcopy(nsd->nsd_cr.cr_groups,
Index: sys/nfs/nfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.171
diff -u -p -r1.171 nfs_vnops.c
--- sys/nfs/nfs_vnops.c	2001/05/23 09:42:05	1.171
+++ sys/nfs/nfs_vnops.c	2001/06/22 14:51:02
@@ -3131,12 +3131,10 @@ nfsspec_access(ap)
 	} */ *ap;
 {
 	register struct vattr *vap;
-	register gid_t *gp;
 	register struct ucred *cred = ap->a_cred;
 	struct vnode *vp = ap->a_vp;
 	mode_t mode = ap->a_mode;
 	struct vattr vattr;
-	register int i;
 	int error;
 
 	/*
@@ -3171,13 +3169,8 @@ nfsspec_access(ap)
 	 */
 	if (cred->cr_uid != vap->va_uid) {
 		mode >>= 3;
-		gp = cred->cr_groups;
-		for (i = 0; i < cred->cr_ngroups; i++, gp++)
-			if (vap->va_gid == *gp)
-				goto found;
-		mode >>= 3;
-found:
-		;
+		if (!groupmember(vap->va_gid, cred))
+			mode >>= 3;
 	}
 	error = (vap->va_mode & mode) == mode ? 0 : EACCES;
 	return (error);
Index: sys/sys/socket.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/socket.h,v
retrieving revision 1.56
diff -u -p -r1.56 socket.h
--- sys/sys/socket.h	2001/06/12 11:12:23	1.56
+++ sys/sys/socket.h	2001/06/22 14:51:02
@@ -359,14 +359,14 @@ struct cmsghdr {
  * Credentials structure, used to verify the identity of a peer
  * process that has sent us a message. This is allocated by the
  * peer process but filled in by the kernel. This prevents the
- * peer from lying about its identity. (Note that cmcred_groups[0]
- * is the effective GID.)
+ * peer from lying about its identity.
  */
 struct cmsgcred {
 	pid_t	cmcred_pid;		/* PID of sending process */
 	uid_t	cmcred_uid;		/* real UID of sending process */
 	uid_t	cmcred_euid;		/* effective UID of sending process */
 	gid_t	cmcred_gid;		/* real GID of sending process */
+	gid_t	cmcred_egid;		/* effective GID of sending process */
 	short	cmcred_ngroups;		/* number or groups */
 	gid_t	cmcred_groups[CMGROUP_MAX];	/* groups */
 };
Index: sys/sys/ucred.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/ucred.h,v
retrieving revision 1.24
diff -u -p -r1.24 ucred.h
--- sys/sys/ucred.h	2001/05/25 16:59:10	1.24
+++ sys/sys/ucred.h	2001/06/22 14:51:02
@@ -54,6 +54,7 @@ struct ucred {
 	uid_t	cr_svuid;		/* saved user id */
 	short	cr_ngroups;		/* number of groups */
 	gid_t	cr_groups[NGROUPS];	/* groups */
+	gid_t	cr_gid;			/* effective group id */
 	gid_t	cr_rgid;		/* real group id */
 	gid_t	cr_svgid;		/* saved user id */
 	struct	uidinfo *cr_uidinfo;	/* per euid resource consumption */
@@ -61,21 +62,18 @@ struct ucred {
 	struct	prison *cr_prison;	/* jail(4) */
 	struct	mtx cr_mtx;		/* protect refcount */
 };
-#define cr_gid cr_groups[0]
 #define NOCRED ((struct ucred *)0)	/* no credential available */
 #define FSCRED ((struct ucred *)-1)	/* filesystem credential */
 
 /*
- * This is the external representation of struct ucred, based upon the
- * size of a 4.2-RELEASE struct ucred.  There will probably never be
- * any need to change the size of this or layout of its used fields.
+ * This is the external representation of struct ucred.
  */
 struct xucred {
 	u_short	_cr_unused0;		/* compatibility with old ucred */
 	uid_t	cr_uid;			/* effective user id */
+	gid_t	cr_gid;			/* effective group id */
 	short	cr_ngroups;		/* number of groups */
 	gid_t	cr_groups[NGROUPS];	/* groups */
-	void	*_cr_unused1;		/* compatibility with old ucred */
 };
 
 #ifdef _KERNEL
Index: sys/sys/user.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/user.h,v
retrieving revision 1.38
diff -u -p -r1.38 user.h
--- sys/sys/user.h	2001/06/10 02:08:36	1.38
+++ sys/sys/user.h	2001/06/22 14:51:02
@@ -74,16 +74,16 @@
  * fill_kinfo_proc and in lib/libkvm/kvm_proc.c in the function kvm_proclist.
  */
 #ifdef	__alpha__
-#define	KINFO_PROC_SIZE	912		/* the correct size for kinfo_proc */
+#define	KINFO_PROC_SIZE	920		/* the correct size for kinfo_proc */
 #endif
 #ifdef	__ia64__
-#define KINFO_PROC_SIZE 888
+#define KINFO_PROC_SIZE 896
 #endif
 #ifdef	__i386__
-#define	KINFO_PROC_SIZE	648		/* the correct size for kinfo_proc */
+#define	KINFO_PROC_SIZE	652		/* the correct size for kinfo_proc */
 #endif
 #ifdef  __powerpc__
-#define	KINFO_PROC_SIZE	656
+#define	KINFO_PROC_SIZE	660
 #endif
 #ifndef	KINFO_PROC_SIZE
 #error	"Unknown architecture"
@@ -117,6 +117,7 @@ struct kinfo_proc {
 	uid_t	ki_uid;			/* effective user id */
 	uid_t	ki_ruid;		/* Real user id */
 	uid_t	ki_svuid;		/* Saved effective user id */
+	gid_t	ki_gid;			/* Effective group id */
 	gid_t	ki_rgid;		/* Real group id */
 	gid_t	ki_svgid;		/* Saved effective group id */
 	short	ki_ngroups;		/* number of groups */
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.169
diff -u -p -r1.169 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c	2001/06/06 17:40:57	1.169
+++ sys/ufs/ufs/ufs_vnops.c	2001/06/22 14:51:03
@@ -1389,8 +1389,8 @@ ufs_mkdir(ap)
 				 */
 				ucred.cr_ref = 1;
 				ucred.cr_uid = ip->i_uid;
-				ucred.cr_ngroups = 1;
-				ucred.cr_groups[0] = dp->i_gid;
+				ucred.cr_ngroups = 0;
+				ucred.cr_gid = dp->i_gid;
 				ucp = &ucred;
 			}
 #endif
@@ -2264,8 +2264,8 @@ ufs_makeinode(mode, dvp, vpp, cnp)
 			 */
 			ucred.cr_ref = 1;
 			ucred.cr_uid = ip->i_uid;
-			ucred.cr_ngroups = 1;
-			ucred.cr_groups[0] = pdir->i_gid;
+			ucred.cr_ngroups = 0;
+			ucred.cr_gid = pdir->i_gid;
 			ucp = &ucred;
 #endif
 		} else
Index: usr.sbin/rpc.lockd/kern.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/rpc.lockd/kern.c,v
retrieving revision 1.3
diff -u -p -r1.3 kern.c
--- usr.sbin/rpc.lockd/kern.c	2001/04/25 18:40:38	1.3
+++ usr.sbin/rpc.lockd/kern.c	2001/06/22 14:51:03
@@ -229,9 +229,9 @@ set_auth(
                 cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth);
         cl->cl_auth = authunix_create(hostname,
                         ucred->cr_uid,
-                        ucred->cr_groups[0],
-                        ucred->cr_ngroups-1,
-                        &ucred->cr_groups[1]);
+                        ucred->cr_gid,
+                        ucred->cr_ngroups,
+                        ucred->cr_groups);
 }
 
 

--nFreZHaLTZJo0R7j
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=ChangeLog

include/grp.h				group.gr_gid's type change: int -> gid_t
include/unistd.h			getgrouplist(), initgroups() prototypes fixed
lib/libc/gen/getgrent.3			reflected grp.h change
lib/libc/gen/getgrouplist.3		getgrouplist() prototype and and Hesiod changes
lib/libc/gen/getgrouplist.c		getgrouplist(): prototype, don't panic if grpcnt == 0, groups[0] is no more egid
lib/libc/gen/initgroups.3		initgroups() prototype changed
lib/libc/gen/initgroups.c		initgroups() prototype changed
lib/libc/sys/recv.2			New: cmsgcred.cmcred_egid
lib/libkvm/kvm_proc.c			New: kproc_info.ki_gid
sbin/mount_portalfs/pt_file.c		New: portal_cred.pcr_gid
sbin/mountd/mountd.c			ucred.cr_groups[0] -> ucred.cr_gid
sbin/nfsd/nfsd.c			ucred.cr_groups[0] -> ucred.cr_gid (XXX: getgroups())
sys/alpha/osf1/osf1_misc.c		ucred.cr_groups[0] -> ucred.cr_gid
sys/coda/coda_vnops.c			debug print of ucred.cr_gid
sys/compat/linux/linux_misc.c		ucred.cr_groups[0] -> ucred.cr_gid
sys/fs/portalfs/portal.h		New: portal_cred.pcr_gid
sys/fs/portalfs/portal_vnops.c		New: portal_cred.pcr_gid
sys/fs/procfs/procfs_mem.c		ucred.cr_groups[0] -> ucred.cr_gid; simplify
sys/fs/procfs/procfs_status.c		ucred.cr_groups[0] -> ucred.cr_gid
sys/fs/umapfs/umap_subr.c		ucred.cr_groups[0] -> ucred.cr_gid
sys/gnu/ext2fs/ext2_vnops.c		ucred.cr_groups[0] -> ucred.cr_gid
sys/kern/kern_proc.c			New: kproc_info.ki_gid
sys/kern/kern_prot.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/kern/uipc_usrreq.c			New: cmsgcred.cmcred_egid
sys/kern/vfs_aio.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/kern/vfs_export.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/kern/vfs_syscalls.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/netinet/tcp_subr.c			New: xucred.cr_gid
sys/netinet/udp_usrreq.c		New: xucred.cr_gid
sys/netinet6/udp6_usrreq.c		New: xucred.cr_gid
sys/netncp/ncp_conn.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/netsmb/smb_conn.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/nfs/nfs_socket.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/nfs/nfs_subs.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/nfs/nfs_syscalls.c			ucred.cr_groups[0] -> ucred.cr_gid
sys/nfs/nfs_vnops.c			ucred.cr_groups[0] -> ucred.cr_gid; simplify
sys/sys/socket.h			New: cmsgcred.cmcred_egid
sys/sys/ucred.h				New: ucred.cr_gid, xucred.cr_gid (XXX)
sys/sys/user.h				New: kinfo_proc.ki_gid (XXX)
sys/ufs/ufs/ufs_vnops.c			ucred.cr_groups[0] -> ucred.cr_gid
usr.sbin/rpc.lockd/kern.c		ucred.cr_groups[0] -> ucred.cr_gid

--nFreZHaLTZJo0R7j--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010622180509.D31008>