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,
[EMAIL PROTECTED]           Sunbay Software AG,
[EMAIL PROTECTED]          FreeBSD committer,
+380.652.512.251        Simferopol, Ukraine

http://www.FreeBSD.org  The Power To Serve
http://www.oracle.com   Enabling The Information Age
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);
 }
 
 
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

Reply via email to