On 23.03-12:23, Boris Kochergin wrote:
[ ... ]
> >yes, that's great but you may be surprised to learn that it doesn't
> >actually solve your problem.  i think (and without looking
> >specifically at the impact my even be confident enough to say
> >definately) if you get a groups list it will only be cropped and the
> >error message is being erroneously avoided, not corrected.  i'd also
> >suggest that you may be opening up your system to some overflows
> >although, generally, the code sections use the same limits and so
> >you might get away with it.
[ ... ]
> On my 7.0 system, and a kernel recompiled with NGROUPS_MAX set to 64, a 
> getgrouplist() call for a user who is in more than 16 groups (24, to be 
> exact) will populate the array specified by the "gid_t *groups" argument 
> with the 24 groups the user is in, in addition to the group specified in 
> the "gid_t basegid" argument. The value of the variable specified in the 
> "int *ngroups" will also be 25, and the getgrouplist() call will return 
> 0. So, as far as being a hack for a specific problem, it seems to work 
> properly.
yeah, looked at it now.  NGROUPS is defined from NGROUPS_MAX (bad
memory).  the other significant values would be KI_NGROUPS which is
not defined from NGROUPS_MAX; neither are the IPC or RPC relevant
values, although, as i said they use their own max values for validation
(i.e. they don't suddenly using NGROUPS_MAX instead of CMGROUPS) so
probably won't overflow trivially but i wouldn't say they are
necissarily safe.

suffice to say if it works for you great but be aware that you may
have security and other issues associated with the change.

[ ... ]
> Sure, I'll test the patch. Can you point me at it?

sure, attached.  but note it's functionally zero progress, it only
looks to remove the dependancy on NGROUPS_MAX as static definition
and make SC_NGROUPS_MAX a writable and referenced value.  however, it
won't currently give you the extra groups you want because it defines
other values from _NGROUP_COMPAT (which is 16) until i can complete
the changes to a stable state.

it would still be nice to know that i haven't messed it up
completely and that, at the very least the system still boots and
runs with it.

p.s: i've gotta finish some bloody web stuff and then i'll throw
some more time at it this afternoon.
-- 
        t
 t
                 w
Index: contrib/openpam/lib/openpam_borrow_cred.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/contrib/openpam/lib/openpam_borrow_cred.c,v
retrieving revision 1.1.1.9
diff -b -u -r1.1.1.9 openpam_borrow_cred.c
--- contrib/openpam/lib/openpam_borrow_cred.c   21 Dec 2007 11:49:29 -0000      
1.1.1.9
+++ contrib/openpam/lib/openpam_borrow_cred.c   4 Feb 2009 16:38:46 -0000
@@ -60,6 +60,7 @@
        struct pam_saved_cred *scred;
        const void *scredp;
        int r;
+       int ngroups ;
 
        ENTERI(pwd->pw_uid);
        r = pam_get_data(pamh, PAM_SAVED_CRED, &scredp);
@@ -73,26 +74,55 @@
                    (int)geteuid());
                RETURNC(PAM_PERM_DENIED);
        }
-       scred = calloc(1, sizeof *scred);
-       if (scred == NULL)
-               RETURNC(PAM_BUF_ERR);
-       scred->euid = geteuid();
-       scred->egid = getegid();
-       r = getgroups(NGROUPS_MAX, scred->groups);
-       if (r < 0) {
-               FREE(scred);
-               RETURNC(PAM_SYSTEM_ERR);
-       }
-       scred->ngroups = r;
+/* get the maximum number of system groups */
+#if _POSIX_VERSION > 199212
+       ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       ngroups = NGROUPS_MAX ;
+#else
+       ngroups = _NGROUPS_COMPAT ;
+#endif
+/* initally allocate enough memory for max_groups */
+       scred = malloc( sizeof(struct pam_saved_cred) +
+                       ngroups*sizeof(gid_t) ) ;
+       if( scred == NULL )
+               RETURNC( PAM_BUF_ERR ) ;
+/* set the save values */
+       scred->euid = geteuid() ;
+       scred->egid = getegid() ;
+/* save groups into our (probably) oversized memory allocation */
+       r = getgroups( ngroups, scred->groups ) ;
+       if( r < 0 ) {
+               FREE( scred ) ; /* call PAM's free macro */
+               RETURNC( PAM_SYSTEM_ERR ) ;
+       } ;
+       scred->ngroups = r ;
+       ngroups = r < ngroups ? r : ngroups ; /* choose the smallest */
+                               /* ... number of groups to allocate */
+       ngroups = ngroups < _NGROUPS_COMPAT ? ngroups : _NGROUPS_COMPAT ;
+                               /* but keep it within expected minimum value */
+                               /*      XXX: we don't really want this but 
until we get
+                                *      educated on the implications this is 
probably safe
+                                *      and certainaly compatible */
+/* realloc, releasing unneeded memory */
+       scred = realloc( (void*)scred,
+                       sizeof(struct pam_saved_cred)+ngroups*sizeof(gid_t) ) ;
+                               /* nb: we ignore failure and try to store the 
larger
+                                * ... structure as initially requested. 
catching the
+                                * ... error in 'pam_set_data' if neccessary. */
+/* save the credentials to PAM user data area */
        r = pam_set_data(pamh, PAM_SAVED_CRED, scred, &openpam_free_data);
        if (r != PAM_SUCCESS) {
                FREE(scred);
                RETURNC(r);
        }
+/* set the new credentials */
        if (geteuid() == pwd->pw_uid)
                RETURNC(PAM_SUCCESS);
        if (initgroups(pwd->pw_name, pwd->pw_gid) < 0 ||
-             setegid(pwd->pw_gid) < 0 || seteuid(pwd->pw_uid) < 0) {
+                       setegid(pwd->pw_gid) < 0 || seteuid(pwd->pw_uid) < 0)
+       {
+       /* if any of the set calls failed, then restore and fail */
                openpam_restore_cred(pamh);
                RETURNC(PAM_SYSTEM_ERR);
        }
Index: contrib/openpam/lib/openpam_impl.h
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/contrib/openpam/lib/openpam_impl.h,v
retrieving revision 1.1.1.17
diff -b -u -r1.1.1.17 openpam_impl.h
--- contrib/openpam/lib/openpam_impl.h  21 Dec 2007 11:49:29 -0000      1.1.1.17
+++ contrib/openpam/lib/openpam_impl.h  5 Feb 2009 15:41:19 -0000
@@ -110,13 +110,17 @@
        int              env_size;
 };
 
-#ifdef NGROUPS_MAX
+#if _POSIX_VERSION > 199212
 #define PAM_SAVED_CRED "pam_saved_cred"
 struct pam_saved_cred {
        uid_t    euid;
        gid_t    egid;
-       gid_t    groups[NGROUPS_MAX];
        int      ngroups;
+       gid_t    groups[];
+                               /* keep this last so that we can simply
+                               .. over-allocate the amount of space
+                               .. nb: don't use sizeof' unless you adjust
+                               .. for the number of groups */
 };
 #endif
 
Index: include/rpc/auth_unix.h
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/include/rpc/auth_unix.h,v
retrieving revision 1.11
diff -b -u -r1.11 auth_unix.h
--- include/rpc/auth_unix.h     23 Mar 2002 17:24:55 -0000      1.11
+++ include/rpc/auth_unix.h     14 Jan 2009 11:15:21 -0000
@@ -52,7 +52,7 @@
 #define MAX_MACHINE_NAME 255
 
 /* gids compose part of a credential; there may not be more than 16 of them */
-#define NGRPS 16
+#define AUTH_UNIX_NGROUPS 16
 
 /*
  * Unix style credentials.
Index: lib/libc/rpc/auth_unix.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/auth_unix.c,v
retrieving revision 1.18
diff -b -u -r1.18 auth_unix.c
--- lib/libc/rpc/auth_unix.c    14 Jun 2007 20:07:35 -0000      1.18
+++ lib/libc/rpc/auth_unix.c    4 Feb 2009 15:31:57 -0000
@@ -182,27 +182,48 @@
  * Returns an auth handle with parameters determined by doing lots of
  * syscalls.
  */
-AUTH *
+AUTH*
 authunix_create_default()
 {
-       int len;
        char machname[MAXHOSTNAMELEN + 1];
+       AUTH* auth_unix ;
        uid_t uid;
        gid_t gid;
-       gid_t gids[NGROUPS_MAX];
-
-       if (gethostname(machname, sizeof machname) == -1)
-               abort();
-       machname[sizeof(machname) - 1] = 0;
+       gid_t *gids ;
+       uint ngroups ;
+       uint max_ngroups ;
+
+/* get hostname or fail */
+       if( gethostname(machname,sizeof(machname)) == -1 )
+               abort() ;
+       machname[sizeof(machname)-1] = 0 ; /* add a null terminator */
+/*     set uid/gid from current effective values */
        uid = geteuid();
        gid = getegid();
-       if ((len = getgroups(NGROUPS_MAX, gids)) < 0)
-               abort();
-       if (len > NGRPS)
-               len = NGRPS;
-       /* XXX: interface problem; those should all have been unsigned */
-       return (authunix_create(machname, (int)uid, (int)gid, len,
-           (int *)gids));
+/*     set the group set */
+#if _POSIX_VERSION > 199212
+       max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_ngroups = NGROUPS_MAX ;
+#else
+       max_ngroups = 16 ;
+#endif
+       gids = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+       if( gids == NULL )
+               abort () ;
+       if( (ngroups=getgroups(max_ngroups,gids)) < 0 ) {
+               free( gids ) ;
+               abort() ;
+       }
+/* clip the groups to a transmissable size */
+       if( ngroups > AUTH_UNIX_NGROUPS )
+               ngroups = AUTH_UNIX_NGROUPS ;
+/* XXX: interface problem; those should all have been unsigned */
+       auth_unix = authunix_create( machname,
+                       (int)uid, (int)gid, (int)ngroups,
+                       (int*)gids ) ;
+       free( (void*)gids ) ;
+       return( auth_unix ) ;
 }
 
 /*
Index: lib/libc/rpc/authunix_prot.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/authunix_prot.c,v
retrieving revision 1.10
diff -b -u -r1.10 authunix_prot.c
--- lib/libc/rpc/authunix_prot.c        20 Nov 2007 01:51:20 -0000      1.10
+++ lib/libc/rpc/authunix_prot.c        4 Feb 2009 16:03:29 -0000
@@ -67,13 +67,14 @@
 
        paup_gids = &p->aup_gids;
 
-       if (xdr_u_long(xdrs, &(p->aup_time))
-           && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
-           && xdr_int(xdrs, &(p->aup_uid))
-           && xdr_int(xdrs, &(p->aup_gid))
-           && xdr_array(xdrs, (char **) paup_gids,
-                   &(p->aup_len), NGRPS, sizeof(int), (xdrproc_t)xdr_int) ) {
-               return (TRUE);
+       if( xdr_u_long(xdrs,&(p->aup_time)) &&
+                       xdr_string(xdrs,&(p->aup_machname),MAX_MACHINE_NAME) &&
+                       xdr_int(xdrs,&(p->aup_uid)) &&
+                       xdr_int(xdrs,&(p->aup_gid)) &&
+                       xdr_array(xdrs,(char**)paup_gids,&(p->aup_len),
+                                       
AUTH_UNIX_NGROUPS,sizeof(int),(xdrproc_t)xdr_int) )
+       {
+               return( TRUE ) ;
        }
-       return (FALSE);
+       return( FALSE ) ;
 }
Index: lib/libc/rpc/netname.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/netname.c,v
retrieving revision 1.8
diff -b -u -r1.8 netname.c
--- lib/libc/rpc/netname.c      16 Oct 2004 06:11:35 -0000      1.8
+++ lib/libc/rpc/netname.c      14 Jan 2009 01:29:47 -0000
@@ -61,6 +61,7 @@
 #ifndef MAXHOSTNAMELEN
 #define MAXHOSTNAMELEN 256
 #endif
+
 #ifndef NGROUPS
 #define NGROUPS 16
 #endif
Index: lib/libc/rpc/netnamer.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/netnamer.c,v
retrieving revision 1.12
diff -b -u -r1.12 netnamer.c
--- lib/libc/rpc/netnamer.c     10 Mar 2005 00:58:21 -0000      1.12
+++ lib/libc/rpc/netnamer.c     3 Feb 2009 17:55:48 -0000
@@ -69,7 +69,6 @@
 #ifndef NGROUPS
 #define NGROUPS 16
 #endif
-
 /*
  * Convert network-name into unix credential
  */
@@ -104,7 +103,7 @@
                        return (0);
                }
                *gidp = (gid_t) atol(p);
-               for (gidlen = 0; gidlen < NGROUPS; gidlen++) {
+               for (gidlen = 0; gidlen < _NGROUPS_RPC_MAX; gidlen++) {
                        p = strsep(&res, "\n,");
                        if (p == NULL)
                                break;
@@ -157,7 +156,7 @@
 static int
 _getgroups(uname, groups)
        char           *uname;
-       gid_t          groups[NGROUPS];
+       gid_t          groups[_NGROUPS_RPC_MAX];
 {
        gid_t           ngroups = 0;
        struct group *grp;
@@ -169,10 +168,11 @@
        while ((grp = getgrent())) {
                for (i = 0; grp->gr_mem[i]; i++)
                        if (!strcmp(grp->gr_mem[i], uname)) {
-                               if (ngroups == NGROUPS) {
+                               if( ngroups == _NGROUPS_RPC_MAX ) {
 #ifdef DEBUG
-                                       fprintf(stderr,
-                               "initgroups: %s is in too many groups\n", 
uname);
+                                       fprintf( stderr,
+                                                       "initgroups: %s is in 
too many groups\n",
+                                                       uname ) ;
 #endif
                                        goto toomany;
                                }
Index: lib/libc/rpc/svc_auth_des.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/svc_auth_des.c,v
retrieving revision 1.9
diff -b -u -r1.9 svc_auth_des.c
--- lib/libc/rpc/svc_auth_des.c 22 Mar 2002 23:18:37 -0000      1.9
+++ lib/libc/rpc/svc_auth_des.c 3 Feb 2009 17:51:01 -0000
@@ -452,7 +452,7 @@
        short uid;              /* cached uid */
        short gid;              /* cached gid */
        short grouplen; /* length of cached groups */
-       short groups[NGROUPS];  /* cached groups */
+       short groups[_NGROUPS_RPC_MAX]; /* cached groups */
 };
 
 /*
Index: lib/libc/rpc/svc_auth_unix.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/libc/rpc/svc_auth_unix.c,v
retrieving revision 1.11
diff -b -u -r1.11 svc_auth_unix.c
--- lib/libc/rpc/svc_auth_unix.c        16 Oct 2004 06:11:35 -0000      1.11
+++ lib/libc/rpc/svc_auth_unix.c        4 Feb 2009 16:04:10 -0000
@@ -68,7 +68,7 @@
        struct area {
                struct authunix_parms area_aup;
                char area_machname[MAX_MACHINE_NAME+1];
-               int area_gids[NGRPS];
+               int area_gids[AUTH_UNIX_NGROUPS] ;
        } *area;
        u_int auth_len;
        size_t str_len, gid_len;
@@ -98,7 +98,7 @@
                aup->aup_uid = (int)IXDR_GET_INT32(buf);
                aup->aup_gid = (int)IXDR_GET_INT32(buf);
                gid_len = (size_t)IXDR_GET_U_INT32(buf);
-               if (gid_len > NGRPS) {
+               if( gid_len > AUTH_UNIX_NGROUPS ) {
                        stat = AUTH_BADCRED;
                        goto done;
                }
Index: lib/librpcsec_gss/svc_rpcsec_gss.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/lib/librpcsec_gss/svc_rpcsec_gss.c,v
retrieving revision 1.4
diff -b -u -r1.4 svc_rpcsec_gss.c
--- lib/librpcsec_gss/svc_rpcsec_gss.c  3 Nov 2008 10:38:00 -0000       1.4
+++ lib/librpcsec_gss/svc_rpcsec_gss.c  5 Feb 2009 16:09:37 -0000
@@ -127,7 +127,7 @@
        rpc_gss_ucred_t         cl_ucred;       /* unix-style credentials */
        bool_t                  cl_done_callback; /* TRUE after call */
        void                    *cl_cookie;     /* user cookie from callback */
-       gid_t                   cl_gid_storage[NGRPS];
+       gid_t                   cl_gid_storage[AUTH_UNIX_NGROUPS];
        gss_OID                 cl_mech;        /* mechanism */
        gss_qop_t               cl_qop;         /* quality of protection */
        u_int                   cl_seq;         /* current sequence number */
@@ -578,7 +578,7 @@
 
        getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
        if (pw) {
-               int len = NGRPS;
+               int len = AUTH_UNIX_NGROUPS;
                uc->uid = pw->pw_uid;
                uc->gid = pw->pw_gid;
                uc->gidlist = client->cl_gid_storage;
Index: sys/compat/svr4/svr4_misc.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/compat/svr4/svr4_misc.c,v
retrieving revision 1.101
diff -b -u -r1.101 svr4_misc.c
--- sys/compat/svr4/svr4_misc.c 21 Apr 2008 21:24:08 -0000      1.101
+++ sys/compat/svr4/svr4_misc.c 14 Jan 2009 11:58:47 -0000
@@ -710,7 +710,12 @@
                *retval = 0;
                break;
        case SVR4_CONFIG_NGROUPS:
-               *retval = NGROUPS_MAX;
+               *retval = _NGROUPS_COMPAT;
+                                       /* XXX: this should pull the value
+                                        *      from sysctl but i cannot find
+                                        *      the definitions for the similar
+                                        *      varaibles here (i.e. 'maxproc')
+                                       */
                break;
        case SVR4_CONFIG_CHILD_MAX:
                *retval = maxproc;
Index: sys/fs/portalfs/portal.h
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/fs/portalfs/portal.h,v
retrieving revision 1.10
diff -b -u -r1.10 portal.h
--- sys/fs/portalfs/portal.h    6 Jan 2005 18:10:40 -0000       1.10
+++ sys/fs/portalfs/portal.h    16 Jan 2009 23:44:50 -0000
@@ -43,7 +43,7 @@
        int             pcr_flag;               /* File open mode */
        uid_t           pcr_uid;                /* From ucred */
        short           pcr_ngroups;            /* From ucred */
-       gid_t           pcr_groups[NGROUPS];    /* From ucred */
+       gid_t           pcr_groups[_NGROUPS_COMPAT];    /* From ucred */
 };
 
 #ifdef _KERNEL
Index: sys/i386/ibcs2/ibcs2_misc.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/i386/ibcs2/ibcs2_misc.c,v
retrieving revision 1.70
diff -b -u -r1.70 ibcs2_misc.c
--- sys/i386/ibcs2/ibcs2_misc.c 13 Jan 2008 14:44:07 -0000      1.70
+++ sys/i386/ibcs2/ibcs2_misc.c 14 Jan 2009 12:24:56 -0000
@@ -659,14 +659,14 @@
        struct thread *td;
        struct ibcs2_getgroups_args *uap;
 {
-       ibcs2_gid_t iset[NGROUPS_MAX];
-       gid_t gp[NGROUPS_MAX];
+       ibcs2_gid_t iset[_NGROUPS_COMPAT];
+       gid_t gp[_NGROUPS_COMPAT];
        u_int i, ngrp;
        int error;
 
        if (uap->gidsetsize < 0)
                return (EINVAL);
-       ngrp = MIN(uap->gidsetsize, NGROUPS_MAX);
+       ngrp = MIN(uap->gidsetsize, _NGROUPS_COMPAT);
        error = kern_getgroups(td, &ngrp, gp);
        if (error)
                return (error);
@@ -685,11 +685,11 @@
        struct thread *td;
        struct ibcs2_setgroups_args *uap;
 {
-       ibcs2_gid_t iset[NGROUPS_MAX];
-       gid_t gp[NGROUPS_MAX];
+       ibcs2_gid_t iset[_NGROUPS_COMPAT];
+       gid_t gp[_NGROUPS_COMPAT];
        int error, i;
 
-       if (uap->gidsetsize < 0 || uap->gidsetsize > NGROUPS_MAX)
+       if (uap->gidsetsize < 0 || uap->gidsetsize > _NGROUPS_COMPAT)
                return (EINVAL);
        if (uap->gidsetsize && uap->gidset) {
                error = copyin(uap->gidset, iset, sizeof(ibcs2_gid_t) *
@@ -789,8 +789,13 @@
                return 0;
 
        case IBCS2_SC_NGROUPS_MAX:
-               mib[1] = KERN_NGROUPS;
-               break;
+                               /*      XXX: IBCS2 compat with group limits not 
known to
+                                *      me, so i'll just return a 
compatibile/safe limit
+                                *      for now */
+               PROC_LOCK(p) ;
+               td->td_retval[0] = _NGROUPS_COMPAT ;
+               PROC_UNLOCK(p) ;
+               return( 0 ) ;
 
        case IBCS2_SC_OPEN_MAX:
                PROC_LOCK(p);
Index: sys/kern/kern_mib.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/kern/kern_mib.c,v
retrieving revision 1.93
diff -b -u -r1.93 kern_mib.c
--- sys/kern/kern_mib.c 28 Jan 2009 19:58:05 -0000      1.93
+++ sys/kern/kern_mib.c 4 Feb 2009 13:15:06 -0000
@@ -124,8 +124,8 @@
 SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD,
     0, _POSIX_VERSION, "Version of POSIX attempting to comply to");
 
-SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD,
-    0, NGROUPS_MAX, "Maximum number of groups a user can belong to");
+SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RW,
+    0, _NGROUPS_COMPAT, "Maximum number of groups allocated to a user");
 
 SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD,
     0, 1, "Whether job control is available");
Index: sys/sys/param.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/sys/param.h,v
retrieving revision 1.382
diff -b -u -r1.382 param.h
--- sys/sys/param.h     28 Jan 2009 17:57:16 -0000      1.382
+++ sys/sys/param.h     4 Feb 2009 14:11:55 -0000
@@ -57,7 +57,7 @@
  *             is created, otherwise 1.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 800062       /* Master, propagated to newvers */
+#define __FreeBSD_version 800060       /* Master, propagated to newvers */
 
 #ifndef LOCORE
 #include <sys/types.h>
@@ -77,7 +77,8 @@
 #define        MAXLOGNAME      17              /* max login name length (incl. 
NUL) */
 #define        MAXUPRC         CHILD_MAX       /* max simultaneous processes */
 #define        NCARGS          ARG_MAX         /* max bytes for an exec 
function */
-#define        NGROUPS         NGROUPS_MAX     /* max number groups */
+#define        NGROUPS         _NGROUPS_COMPAT
+                       /* depreciated check sysctl/sysconf for NGROUPS_MAX 
value instead */
 #define        NOFILE          OPEN_MAX        /* max open files per process */
 #define        NOGROUP         65535           /* marker for empty group set 
member */
 #define MAXHOSTNAMELEN 256             /* max hostname size */
Index: sys/sys/syslimits.h
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/sys/sys/syslimits.h,v
retrieving revision 1.23
diff -b -u -r1.23 syslimits.h
--- sys/sys/syslimits.h 29 May 2007 15:14:46 -0000      1.23
+++ sys/sys/syslimits.h 3 Feb 2009 18:02:22 -0000
@@ -54,7 +54,6 @@
 #define        MAX_CANON                 255   /* max bytes in term canon 
input line */
 #define        MAX_INPUT                 255   /* max bytes in terminal input 
*/
 #define        NAME_MAX                  255   /* max bytes in a file name */
-#define        NGROUPS_MAX                16   /* max supplemental group id's 
*/
 #ifndef OPEN_MAX
 #define        OPEN_MAX                   64   /* max open files per process */
 #endif
@@ -66,9 +65,35 @@
  * We leave the following values undefined to force applications to either
  * assume conservative values or call sysconf() to get the current value.
  *
- * HOST_NAME_MAX
+ * HOST_NAME_MAX NGROUPS_MAX
  *
  * (We should do this for most of the values currently defined here,
  * but many programs are not prepared to deal with this yet.)
  */
+/*
+ * here are some reference values in respect of the obsoleted
+ * NGROUPS_MAX value.
+ *     nb: some apps appear to check NGROUPS_MAX as meaning that
+ * ... system has user groups (i.e. to #ifdef chunks of code).
+ * ... this is easy to change but maybe historically defined?
+ */
+#define        _NGROUPS_RPC_MAX 16 /* reference only */
+                       /*      nb: this is the old system max, so named
+                        *      ... because it's limit appears to
+                        *      ... have been derived from a limitation
+                        *      ... in RPC (and thereby NFS), where it's
+                        *      ... the max number of groups we can exchange */
+#define        _NGROUPS_COMPAT _NGROUPS_RPC_MAX /* reference only */
+                       /*      nb: although this is defined as equal to the rpc
+                        *      ... limit, i have defined it distintly so that
+                        *      ... we may distinguish (whilst updating) usage
+                        *      ... that is correctly explicit (i.e. should be 
16)
+                        *      ... and usage that is only 16 because of an 
expected
+                        *      ... convention.  hopefully we may remove these 
and
+                        *      ... define additional _NGROUPS_*_MAX for those 
defined
+                        *      ... uses. */
+#define        _NGROUPS_SYS_MAX 65536 /* reference only */
+                       /*      nb: the idea's to have this extensible
+                        *      ... indefinately, this is what linux have and
+                        *      ... should more than cover immediate needs */
 #endif
Index: usr.bin/catman/catman.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.bin/catman/catman.c,v
retrieving revision 1.14
diff -b -u -r1.14 catman.c
--- usr.bin/catman/catman.c     5 Dec 2005 14:22:12 -0000       1.14
+++ usr.bin/catman/catman.c     8 Feb 2009 22:51:44 -0000
@@ -93,8 +93,9 @@
 enum Ziptype {NONE, BZIP, GZIP};
 
 static uid_t uid;
-static gid_t gids[NGROUPS_MAX];
+static gid_t *gids;
 static int ngids;
+static int max_ngroups ;
 static int starting_dir;
 static char tmp_file[MAXPATHLEN];
 struct stat test_st;
@@ -789,7 +790,15 @@
                        /* NOTREACHED */
                }
        }
-       ngids = getgroups(NGROUPS_MAX, gids);
+/* allocate memory for group ids */
+#if _POSIX_VERSION > 199212
+       max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_ngroups = NGROUPS_MAX ;
+#else
+       max_ngroups = _NGROUPS_COMPAT ;
+#endif
+       ngids = getgroups( max_ngroups, gids ) ;
        if ((starting_dir = open(".", 0)) < 0) {
                err(1, ".");
        }
Index: usr.bin/newgrp/newgrp.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.bin/newgrp/newgrp.c,v
retrieving revision 1.2
diff -b -u -r1.2 newgrp.c
--- usr.bin/newgrp/newgrp.c     30 Oct 2003 15:14:34 -0000      1.2
+++ usr.bin/newgrp/newgrp.c     9 Feb 2009 22:05:53 -0000
@@ -146,9 +146,10 @@
 static void
 addgroup(const char *grpname)
 {
-       gid_t grps[NGROUPS_MAX];
+       gid_t *grps;
        long lgid;
-       int dbmember, i, ngrps;
+       int dbmember, i, ngrps, max_ngroups ;
+                               /*      XXX: should 'max_ngroups' be a static 
const variable? */
        gid_t egid;
        struct group *grp;
        char *ep, *pass;
@@ -185,9 +186,21 @@
                }
        }
 
-       if ((ngrps = getgroups(NGROUPS_MAX, (gid_t *)grps)) < 0) {
+#if _POSIX_VERSION >= 199212
+       max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_ngroups = NGROUPS_MAX ;
+#else
+       max_ngroups = _NGROUPS_COMPAT ;
+#endif
+       grps = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+       if( grps == NULL ) {
+               warn( "group set memory allocation" ) ;
+               return ;
+       }
+       if( (ngrps=getgroups(max_ngroups,(gid_t*)grps)) < 0 ) {
                warn("getgroups");
-               return;
+               goto error_free ;
        }
 
        /* Remove requested gid from supp. list if it exists. */
@@ -201,7 +214,7 @@
                if (setgroups(ngrps, (const gid_t *)grps) < 0) {
                        PRIV_END;
                        warn("setgroups");
-                       return;
+                       goto error_free ;
                }
                PRIV_END;
        }
@@ -210,14 +223,14 @@
        if (setgid(grp->gr_gid)) {
                PRIV_END;
                warn("setgid");
-               return;
+               goto error_free ;
        }
        PRIV_END;
        grps[0] = grp->gr_gid;
 
        /* Add old effective gid to supp. list if it does not exist. */
        if (egid != grp->gr_gid && !inarray(egid, grps, ngrps)) {
-               if (ngrps == NGROUPS_MAX)
+               if( ngrps == max_ngroups )
                        warnx("too many groups");
                else {
                        grps[ngrps++] = egid;
@@ -225,12 +238,15 @@
                        if (setgroups(ngrps, (const gid_t *)grps)) {
                                PRIV_END;
                                warn("setgroups");
-                               return;
+                               goto error_free ;
                        }
                        PRIV_END;
                }
        }
 
+error_free:
+       free( grps ) ;
+       return ;
 }
 
 static int
Index: usr.sbin/chown/chown.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/chown/chown.c,v
retrieving revision 1.29
diff -b -u -r1.29 chown.c
--- usr.sbin/chown/chown.c      7 Aug 2004 04:19:37 -0000       1.29
+++ usr.sbin/chown/chown.c      8 Feb 2009 16:22:31 -0000
@@ -269,7 +269,8 @@
 {
        static uid_t euid = -1;
        static int ngroups = -1;
-       gid_t groups[NGROUPS_MAX];
+       static int max_groups ;
+       gid_t *groups;
 
        /* Check for chown without being root. */
        if (errno != EPERM || (uid != (uid_t)-1 &&
@@ -279,16 +280,31 @@
        }
 
        /* Check group membership; kernel just returns EPERM. */
+#if _POSIX_VERSION >= 199212
+       max_groups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_groups = NGROUPS_MAX ;
+#else
+       max_groups = _NGROUPS_COMPAT ;
+#endif
+       groups = (gid_t*)calloc( max_groups, sizeof(gid_t) ) ;
+       if( groups == NULL ) {
+               warnx( "failed to allocate memory for group set" ) ;
+               goto exit_cleanup ;
+       }
        if (gid != (gid_t)-1 && ngroups == -1 &&
            euid == (uid_t)-1 && (euid = geteuid()) != 0) {
-               ngroups = getgroups(NGROUPS_MAX, groups);
+               ngroups = getgroups( max_groups, groups ) ;
                while (--ngroups >= 0 && gid != groups[ngroups]);
                if (ngroups < 0) {
                        warnx("you are not a member of group %s", gname);
-                       return;
+                       goto exit_cleanup ;
                }
        }
        warn("%s", file);
+exit_cleanup:
+       free( groups ) ;
+       return ;
 }
 
 void
Index: usr.sbin/chroot/chroot.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/chroot/chroot.c,v
retrieving revision 1.11
diff -b -u -r1.11 chroot.c
--- usr.sbin/chroot/chroot.c    7 Aug 2004 04:19:37 -0000       1.11
+++ usr.sbin/chroot/chroot.c    5 Feb 2009 23:29:48 -0000
@@ -59,6 +59,7 @@
 char   *user;          /* user to switch to before running program */
 char   *group;         /* group to switch to ... */
 char   *grouplist;     /* group list to switch to ... */
+int    max_ngroups;    /* max number of groups allowable */
 
 int
 main(argc, argv)
@@ -69,12 +70,25 @@
        struct passwd   *pw;
        char            *endp, *p;
        const char      *shell;
-       gid_t           gid, gidlist[NGROUPS_MAX];
+       gid_t           gid, *gidlist ;
        uid_t           uid;
-       int             ch, gids;
+       int             ch, gids ;
 
+/*     set some defaults */
        gid = 0;
        uid = 0;
+       user = NULL ;
+       group = NULL ;
+       grouplist = NULL ;
+#if _POSIX_VERSION >= 199212
+       max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_ngroups = NGROUPS_MAX ;
+#else
+       max_ngroups = _NGROUPS_COMPAT ;
+#endif
+
+/*     process command line options */
        while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
                switch(ch) {
                case 'u':
@@ -103,9 +117,12 @@
        if (argc < 1)
                usage();
 
+/*     if a group argument was passed then process it */
        if (group != NULL) {
+       /* if the first char's a digit then assume it's a gid ... */
                if (isdigit((unsigned char)*group)) {
                        gid = (gid_t)strtoul(group, &endp, 0);
+               /*      ... and back out that assumption if it proves wrong */
                        if (*endp != '\0')
                                goto getgroup;
                } else {
@@ -117,8 +134,15 @@
                }
        }
 
-       for (gids = 0;
-           (p = strsep(&grouplist, ",")) != NULL && gids < NGROUPS_MAX; ) {
+/*     process command line group list */
+       if( grouplist != NULL ) {
+               gidlist = (gid_t*)calloc( max_ngroups, sizeof(gid_t) ) ;
+               if( gidlist == NULL )
+                       errx( 1, "inadquate memory for group list" ) ;
+               for( gids = 0 ;
+                               gids < max_ngroups &&
+                                               (p=strsep(&grouplist,",")) != 
NULL ; )
+               {
                if (*p == '\0')
                        continue;
 
@@ -135,9 +159,11 @@
                }
                gids++;
        }
-       if (p != NULL && gids == NGROUPS_MAX)
+               if( p != NULL && gids == max_ngroups )
                errx(1, "too many supplementary groups provided");
+       }
 
+/*     set user from command line option, if supplied */
        if (user != NULL) {
                if (isdigit((unsigned char)*user)) {
                        uid = (uid_t)strtoul(user, &endp, 0);
@@ -152,9 +178,11 @@
                }
        }
 
+/*     change root */
        if (chdir(argv[0]) == -1 || chroot(".") == -1)
                err(1, "%s", argv[0]);
 
+/*     set credentials */
        if (gids && setgroups(gids, gidlist) == -1)
                err(1, "setgroups");
        if (group && setgid(gid) == -1)
@@ -162,11 +190,14 @@
        if (user && setuid(uid) == -1)
                err(1, "setuid");
 
+/*     exec the remaining arguments as the chroot'd command ... */
        if (argv[1]) {
                execvp(argv[1], &argv[1]);
                err(1, "%s", argv[1]);
+               /* NOTREACHED */
        }
 
+/* ... or execute the default system shell */
        if (!(shell = getenv("SHELL")))
                shell = _PATH_BSHELL;
        execlp(shell, shell, "-i", (char *)NULL);
Index: usr.sbin/gssd/gssd.c
===================================================================
RCS file: /home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/gssd/gssd.c,v
retrieving revision 1.1
diff -b -u -r1.1 gssd.c
--- usr.sbin/gssd/gssd.c        3 Nov 2008 10:38:00 -0000       1.1
+++ usr.sbin/gssd/gssd.c        5 Feb 2009 16:16:37 -0000
@@ -464,8 +464,8 @@
                        result->uid = uid;
                        getpwuid_r(uid, &pwd, buf, sizeof(buf), &pw);
                        if (pw) {
-                               int len = NGRPS;
-                               int groups[NGRPS];
+                               int len = AUTH_UNIX_NGROUPS ;
+                               int groups[AUTH_UNIX_NGROUPS] ;
                                result->gid = pw->pw_gid;
                                getgrouplist(pw->pw_name, pw->pw_gid,
                                    groups, &len);
Index: usr.sbin/mount_portalfs/cred.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/mount_portalfs/cred.c,v
retrieving revision 1.1
diff -b -u -r1.1 cred.c
--- usr.sbin/mount_portalfs/cred.c      11 Mar 2005 08:39:58 -0000      1.1
+++ usr.sbin/mount_portalfs/cred.c      16 Jan 2009 23:49:36 -0000
@@ -46,7 +46,7 @@
 set_user_credentials(struct portal_cred *user, struct portal_cred *save)
 {
        save->pcr_uid = geteuid();
-       if ((save->pcr_ngroups = getgroups(NGROUPS_MAX, save->pcr_groups)) < 0)
+       if( (save->pcr_ngroups=getgroups(_NGROUPS_COMPAT,save->pcr_groups)) < 0 
)
                return (-1);
        if (setgroups(user->pcr_ngroups, user->pcr_groups) < 0)
                return (-1);
Index: usr.sbin/pppd/options.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/pppd/options.c,v
retrieving revision 1.26
diff -b -u -r1.26 options.c
--- usr.sbin/pppd/options.c     7 Nov 2007 10:53:38 -0000       1.26
+++ usr.sbin/pppd/options.c     10 Feb 2009 09:11:47 -0000
@@ -72,10 +72,6 @@
 char *strdup(char *);
 #endif
 
-#ifndef GIDSET_TYPE
-#define GIDSET_TYPE    gid_t
-#endif
-
 /*
  * Option variables and default values.
  */
@@ -779,23 +775,64 @@
     int fd;
 {
     uid_t uid;
-    int ngroups, i;
+       int ngroups, max_ngroups, i;
     struct stat sbuf;
-    GIDSET_TYPE groups[NGROUPS_MAX];
+       gid_t *groups;
 
+/*     get the uid */
     uid = getuid();
+/*     ... and return true if root */
+/*     XXX: needs credential check */
     if (uid == 0)
        return 1;
+
+/*     if we're not root, get some info about the file */
     if (fstat(fd, &sbuf) != 0)
        return 0;
+
+/*     test for owner match with current process */
     if (sbuf.st_uid == uid)
        return sbuf.st_mode & S_IRUSR;
+/*     ... and a group match */
     if (sbuf.st_gid == getgid())
        return sbuf.st_mode & S_IRGRP;
-    ngroups = getgroups(NGROUPS_MAX, groups);
-    for (i = 0; i < ngroups; ++i)
-       if (sbuf.st_gid == groups[i])
-           return sbuf.st_mode & S_IRGRP;
+
+/*     if we've still no luck then check the group list for permission match */
+#if _POSIX_VERSION >= 199212
+       max_ngroups = sysconf( _SC_NGROUPS_MAX ) ;
+#elif defined(NGROUPS_MAX)
+       max_ngroups = NGROUPS_MAX ;
+#else
+       max_ngroups = _NGROUPS_COMPAT ;
+#endif
+       groups = (gid_t*) calloc( max_ngroups, sizeof(gid_t) ) ;
+       if( groups == NULL ) {
+       /* if we cannot check groups correctly then assume 'fd' is unreadable
+        *      XXX: this may be false as the converse is more likely.
+        *      i.e. it would be failed readable on available groups
+        *      and granted on full list, however, we just can't be
+        *      psychic and i'm not about to code some idiotic loop that tries
+        *      to get 'some' memory for partial testing.  probably a better
+        *      recourse would be to simply die here but that seems severe
+        *      for a 'readable' test.
+        *      NB: we don't need a 'full' allocation of memory to test the
+        *      group list, only to store it.  one idea would be to do this in
+        *      'blocks'
+        */
+               option_error( 1, "unable to allocate memory for group list" ) ;
+               return( 0 ) ;
+       }
+/*     get groups */
+       ngroups = getgroups( max_ngroups, groups ) ;
+/* ... and test the group permission if matching */
+       for( i = 0 ; i < ngroups ; ++i ) {
+               if (sbuf.st_gid == groups[i]) {
+                       free( (void*)groups) ;
+                       return( sbuf.st_mode & S_IRGRP ) ;
+               }
+       }
+/* otherwise return other permissions match */
+       free( (void*)groups ) ;
     return sbuf.st_mode & S_IROTH;
 }
 
Index: usr.sbin/rpc.lockd/kern.c
===================================================================
RCS file: 
/home/__orole/dev/cabinet/zeeNi/ai/freebsd/src/usr.sbin/rpc.lockd/kern.c,v
retrieving revision 1.21
diff -b -u -r1.21 kern.c
--- usr.sbin/rpc.lockd/kern.c   17 Aug 2006 05:55:20 -0000      1.21
+++ usr.sbin/rpc.lockd/kern.c   5 Feb 2009 16:22:17 -0000
@@ -239,15 +239,15 @@
        int ngroups;
 
        ngroups = xucred->cr_ngroups - 1;
-       if (ngroups > NGRPS)
-               ngroups = NGRPS;
-        if (cl->cl_auth != NULL)
-                cl->cl_auth->ah_ops->ah_destroy(cl->cl_auth);
-        cl->cl_auth = authunix_create(hostname,
+       if( ngroups > AUTH_UNIX_NGROUPS )
+               ngroups = AUTH_UNIX_NGROUPS ;
+       if( cl->cl_auth != NULL )
+               cl->cl_auth->ah_ops->ah_destroy( cl->cl_auth ) ;
+       cl->cl_auth = authunix_create( hostname,
                         xucred->cr_uid,
                         xucred->cr_groups[0],
                         ngroups,
-                        &xucred->cr_groups[1]);
+                       &xucred->cr_groups[1] ) ;
 }
 
 
_______________________________________________
freebsd-hackers@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"

Reply via email to