getgroups() is broken

Few quiestions:

Why does getgroups() always return 0, even when process uid has
supplementary groups?
Why doesn’t ‘id’ utility print suplementary groups for a user? Because
of the above, huh?
Why do headers define NGROUPS_MAX as 8, _SC_NGROUPS_MAX as 4 and
_POSIX_NGROUPS_MAX as 0?
Why does initgroups() has to be different from Unix?

I’m trying to be nice, but I want to SCREAM! Just spent 2 days trying to
understand why something does not work, under assumption that C library
functions do what they’re documented to do. Try example from getgroups()
doc…

  • igor

???

Igor Kovalenko wrote:

Few quiestions:

Why does getgroups() always return 0, even when process uid has
supplementary groups?
Why doesn’t ‘id’ utility print suplementary groups for a user? Because
of the above, huh?
Why do headers define NGROUPS_MAX as 8, _SC_NGROUPS_MAX as 4 and
_POSIX_NGROUPS_MAX as 0?
Why does initgroups() has to be different from Unix?

I’m trying to be nice, but I want to SCREAM! Just spent 2 days trying to
understand why something does not work, under assumption that C library
functions do what they’re documented to do. Try example from getgroups()
doc…

  • igor

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:
: ???
!!!

Geeze man it isn’t like there are a few things that other people
are remarking on =;-) … we didn’t forget about you … remember
you got a shirt!

: Igor Kovalenko wrote:
:> Few quiestions:
:>
:> Why does getgroups() always return 0, even when process uid has
:> supplementary groups?

Because there is/was a bug in the getgroups() routine. It is
fixed now, but won’t make the next patch unfortunately. To
work around if for the time being, always pass in NGROUPS_MAX
to the getgroups() routine (along with an array of NGROUPS_MAX
of course). It was the 0 value that was messing up the function.

:> Why doesn’t ‘id’ utility print suplementary groups for a user? Because
:> of the above, huh?

It does print the values on my RTP system …

% cat /etc/group
root:x:0:root
[snipped for brevity]
ftp:x:80:ftp,root
guest:x:90:thomasf
nobody:x:99:thomasf techies:x:120:
% id
uid=360(thomasf) gid=120(techies) groups=90(guest),99(nobody)

The catch here is that if you modify the /etc/group entry
and then do id without re-logging in (since that is where
the initgroups() call is made) then you don’t see the
updated values.

:> Why do headers define NGROUPS_MAX as 8, _SC_NGROUPS_MAX as 4 and
:> _POSIX_NGROUPS_MAX as 0?

I have NGROUPS_MAX = 8, _SC_NGROUPS_MAX = 8 and _POSIX_NGROUPS_MAX = 0.

Here is the rational for the values:

Posix section 2.8.2 states that the symbols defined
in <limits.h> (which includes _POSIX_NGROUPS_MAX) shall
be defined with the minimum values shown (ie 0 for
_POSIX_NGROUPS_MAX). These represent the very minimum
that a POSIX system would comply to (ie no process
group support). Conforming implementations provide
values at least as large as these values.

NGROUPS_MAX is a specific implementation instance
(as described in section 2.8.3) which is allowed
to be higher than the value defined in <limits.h>.
However, since this is a potentially run-time
variable thing, the specific instance shall be
provided by the sysconf(_SC_NGROUPS_MAX) function.

Phew … there you go.

:> Why does initgroups() has to be different from Unix?

As far as I know it isn’t different from other Unix
systems … if it is then let me know how and we
will see what we can do.

:> I’m trying to be nice, but I want to SCREAM! Just spent 2 days trying to
:> understand why something does not work, under assumption that C library
:> functions do what they’re documented to do. Try example from getgroups()
:> doc…

Sorry … thanks for pointing out a problem and
helping us to get a fix in for it.

Thomas

Thomas (toe-mah) Fletcher QNX Software Systems
thomasf@qnx.com Neutrino Development Group
(613)-591-0931 http://www.qnx.com/~thomasf

Thomas Fletcher wrote:

Igor Kovalenko <> Igor.Kovalenko@motorola.com> > wrote:
: ???
!!!

Geeze man it isn’t like there are a few things that other people
are remarking on =;-) … we didn’t forget about you … remember
you got a shirt!

I don’t think you forget about me, I just feel uneasy unless I have an
ack. Even quick ‘I see the problem’ would do. Otherwise there is always
a possibility that it was overlooked and won’t be fixed.

of course). It was the 0 value that was messing up the function.

thanks.

:> Why doesn’t ‘id’ utility print suplementary groups for a user? Because
:> of the above, huh?

It does print the values on my RTP system …

% cat /etc/group
root> :x:> 0:root
[snipped for brevity]
ftp> :x:> 80:ftp,root
guest> :x:> 90:thomasf
nobody> :x:> 99:thomasf techies> :x:> 120:
% id
uid=360(thomasf) gid=120(techies) groups=90(guest),99(nobody)

I understand where initgroups is called, so I did login. It did not work
on my system.

provided by the sysconf(_SC_NGROUPS_MAX) function.

Ok, just make sure _SC_NGROUPS_MAX == NGROUPS_MAX (it is not, in the
release).

Phew … there you go.

:> Why does initgroups() has to be different from Unix?

As far as I know it isn’t different from other Unix
systems … if it is then let me know how and we
will see what we can do.

Docs say that unlike most Unices it does not add primary group :wink:

  • igor

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:
: Thomas Fletcher wrote:
:>
:> Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:
:> : ???
:> !!!
:>
:> Geeze man it isn’t like there are a few things that other people
:> are remarking on =;-) … we didn’t forget about you … remember
:> you got a shirt!

: I don’t think you forget about me, I just feel uneasy unless I have an
: ack. Even quick ‘I see the problem’ would do. Otherwise there is always
: a possibility that it was overlooked and won’t be fixed.


:> of course). It was the 0 value that was messing up the function.

: thanks.

:> :> Why doesn’t ‘id’ utility print suplementary groups for a user? Because
:> :> of the above, huh?
:>
:> It does print the values on my RTP system …
:>
:> % cat /etc/group
:> root:x:0:root
:> [snipped for brevity]
:> ftp:x:80:ftp,root
:> guest:x:90:thomasf
:> nobody:x:99:thomasf techies:x:120:
:> % id
:> uid=360(thomasf) gid=120(techies) groups=90(guest),99(nobody)
:>

: I understand where initgroups is called, so I did login. It did not work
: on my system.

Odd. What are you running? An original 2.0 + patch Neutrino system
or an RTP (mine was RTP incidentally). According to the login utility
change logs this was changed last september.

:> provided by the sysconf(_SC_NGROUPS_MAX) function.

: Ok, just make sure _SC_NGROUPS_MAX == NGROUPS_MAX (it is not, in the
: release).

Odd. Again my tests indicated that it was the same
on the RTP release.

:> :> Why does initgroups() has to be different from Unix?
:>
:> As far as I know it isn’t different from other Unix
:> systems … if it is then let me know how and we
:> will see what we can do.

: Docs say that unlike most Unices it does not add primary group :wink:

Well you have to agree that this is kind of stupid. If
you were checking for group membership then you would just
not bother with the query if the group matches. If you
are reporting group information then you get one extra
group element … it is very easy to add your element
as an extra in the array.

In any case … your comment is noted … we will take
it under advisement =;-)

Thomas

Thomas (toe-mah) Fletcher QNX Software Systems
thomasf@qnx.com Neutrino Development Group
(613)-591-0931 http://www.qnx.com/~thomasf

Thomas Fletcher wrote:

:> % cat /etc/group
:> root> :x:> 0:root
:> [snipped for brevity]
:> ftp> :x:> 80:ftp,root
:> guest> :x:> 90:thomasf
:> nobody> :x:> 99:thomasf techies> :x:> 120:
:> % id
:> uid=360(thomasf) gid=120(techies) groups=90(guest),99(nobody)
:

: I understand where initgroups is called, so I did login. It did not work
: on my system.

Odd. What are you running? An original 2.0 + patch Neutrino system
or an RTP (mine was RTP incidentally). According to the login utility
change logs this was changed last september.

$ uname -a
QNX lamborgini 6.00 2000/09/13-14:09:41edt x86pc x86
(I’m sure QNX people can easily recognize if it is RTP or OEM).

$ cat /etc/passwd

igor:x:100:100:igor:/home/igor:/bin/sh

$ cat /etc/group

users:x:100:
other:x:101:igor

$ id
uid=100(igor) gid=100

:> provided by the sysconf(_SC_NGROUPS_MAX) function.

: Ok, just make sure _SC_NGROUPS_MAX == NGROUPS_MAX (it is not, in the
: release).

Odd. Again my tests indicated that it was the same
on the RTP release.

find /usr/include -name ‘*.h’ -exec “grep NGROUPS {} && echo {}”

#define _SC_NGROUPS_MAX 4
/usr/include/confname.h
#define _POSIX_NGROUPS_MAX 0 /* Num. simultaneous
supplementary /
#define NGROUPS_MAX 8 /
Num. simultaneous
supplementary /
/usr/include/limits.h
gid_t
grouplist[NGROUPS_MAX];
/usr/include/sys/neutrino.h
#define KERN_NGROUPS 18 /
int: # of supplemental group
ids */
/usr/include/sys/sysctl.h

Wow, I forgot to mention KERN_NGROUPS :wink:
Indeed, this is odd. Must mean your version control system is less than
effective :wink:

Well you have to agree that this is kind of stupid. If
you were checking for group membership then you would just
not bother with the query if the group matches. If you
are reporting group information then you get one extra
group element … it is very easy to add your element
as an extra in the array.

You miss the point. May be it is stupid, but that is what applications
expect. If some piece of Unix code relies on initgroups() to include
primary group, we’re in trouble. The configure script will find out
initgroups() is available, code will happily use it, compile fine, but
then fail in bloody mysterious ways at runtime.

I had this situation with ProFTPD - broken getgroups() was causing
‘guest’ accounts to not work properly ONLY if group name was used to
define guest class, otherwise it worked fine. Took me 2 days to
figure… In many cases errors of that kind will be very hard to detect
and broken packages will be distributed. I found it only because I
needed that particular functionality.

In any case … your comment is noted … we will take
it under advisement =;-)

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

See you,

  • igor

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

Er, we’d like to announce that management has graciously decided
that all of R&D need some R&R, and will all be on holiday in Cuba
for the next week. ;v)


cburgess@qnx.com

Hmm, always wanted to visit Cuba… Still having USSR passport should be
easy to do :wink:

Colin Burgess wrote:

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

Er, we’d like to announce that management has graciously decided
that all of R&D need some R&R, and will all be on holiday in Cuba
for the next week. ;v)


cburgess@qnx.com

It appears my posting from home last night got munged …
try it again:

On Mon, 23 Oct 2000, Igor Kovalenko wrote:

Thomas Fletcher wrote:

:> % cat /etc/group
:> root> :x:> 0:root
:> [snipped for brevity]
:> ftp> :x:> 80:ftp,root
:> guest> :x:> 90:thomasf
:> nobody> :x:> 99:thomasf techies> :x:> 120:
:> % id
:> uid=360(thomasf) gid=120(techies) groups=90(guest),99(nobody)
:

: I understand where initgroups is called, so I did login. It did not work
: on my system.

Odd. What are you running? An original 2.0 + patch Neutrino system
or an RTP (mine was RTP incidentally). According to the login utility
change logs this was changed last september.


$ uname -a
QNX lamborgini 6.00 2000/09/13-14:09:41edt x86pc x86
(I’m sure QNX people can easily recognize if it is RTP or OEM).

$ cat /etc/passwd

igor> :x:> 100> :100:> igor:/home/igor:/bin/sh

$ cat /etc/group

users> :x:> 100:
other> :x:> 101:igor

$ id
uid=100(igor) gid=100

Ah yes of course … you only have one other group specified =;-)
(my test had two groups specified)

I’m at home right now but it looks like there might be a bug in
‘id’ where it (Thomas begins to eat humble pie) looks like
it might expect the return value to include the group member
itself. Mmmmm mmm loving that pie!

:> provided by the sysconf(_SC_NGROUPS_MAX) function.

: Ok, just make sure _SC_NGROUPS_MAX == NGROUPS_MAX (it is not, in the
: release).

Odd. Again my tests indicated that it was the same
on the RTP release.

find /usr/include -name ‘*.h’ -exec “grep NGROUPS {} && echo {}”

#define _SC_NGROUPS_MAX 4
/usr/include/confname.h
#define _POSIX_NGROUPS_MAX 0 /* Num. simultaneous
supplementary /
#define NGROUPS_MAX 8 /
Num. simultaneous
supplementary /
/usr/include/limits.h
gid_t
grouplist[NGROUPS_MAX];
/usr/include/sys/neutrino.h
#define KERN_NGROUPS 18 /
int: # of supplemental group
ids */
/usr/include/sys/sysctl.h

Wow, I forgot to mention KERN_NGROUPS > :wink:
Indeed, this is odd. Must mean your version control system is less than
effective > :wink:

No it has nothing to do with the version control system. You
will note in me previous messages (and from the header file)
that _SC_NGROUPS_MAX is a sysconf. You will note that

NGROUPS_MAX == sysconf(_SC_NGROUPS_MAX)

As for the KERN_NGROUPS it is part of the BSD sysctl.h
header file.

Now you can’t blame me if you just go grepping headers
for values and take them out of context.

Well you have to agree that this is kind of stupid. If
you were checking for group membership then you would just
not bother with the query if the group matches. If you
are reporting group information then you get one extra
group element … it is very easy to add your element
as an extra in the array.


You miss the point. May be it is stupid, but that is what applications
expect. If some piece of Unix code relies on initgroups() to include
primary group, we’re in trouble. The configure script will find out
initgroups() is available, code will happily use it, compile fine, but
then fail in bloody mysterious ways at runtime.

I had this situation with ProFTPD - broken getgroups() was causing
‘guest’ accounts to not work properly ONLY if group name was used to
define guest class, otherwise it worked fine. Took me 2 days to
figure… In many cases errors of that kind will be very hard to detect
and broken packages will be distributed. I found it only because I
needed that particular functionality.

In any case … your comment is noted … we will take
it under advisement =;-)

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

Well then the first beer will be on me …

Thomas … still munching on that humble pie

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:

Hmm, always wanted to visit Cuba… Still having USSR passport should be
easy to do > :wink:

Will they accept a passport from a country that no longer exists? ;v)

Colin Burgess wrote:

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

Er, we’d like to announce that management has graciously decided
that all of R&D need some R&R, and will all be on holiday in Cuba
for the next week. ;v)


cburgess@qnx.com


cburgess@qnx.com

Colin Burgess wrote:

Igor Kovalenko <> Igor.Kovalenko@motorola.com> > wrote:
Hmm, always wanted to visit Cuba… Still having USSR passport should be
easy to do > :wink:

Will they accept a passport from a country that no longer exists? ;v)

If US does, why wouldn’t they? Besides, its spirit is alive still, at
least on Cuba :wink:

Colin Burgess wrote:

One might be wondering what does that mean. I’m coming to Kanata next
week, you better fix it or hide! >:)

Er, we’d like to announce that management has graciously decided
that all of R&D need some R&R, and will all be on holiday in Cuba
for the next week. ;v)


cburgess@qnx.com


cburgess@qnx.com

Thomas Fletcher wrote:

I’m at home right now but it looks like there might be a bug in
‘id’ where it (Thomas begins to eat humble pie) looks like
it might expect the return value to include the group member
itself. Mmmmm mmm loving that pie!

I’d say the bug is not in ‘id’, it’s probably in initgroups() :wink:
If you fix ‘id’ how do you know it won’t show up somewhere else?

No it has nothing to do with the version control system. You
will note in me previous messages (and from the header file)
that _SC_NGROUPS_MAX is a sysconf. You will note that

NGROUPS_MAX == sysconf(_SC_NGROUPS_MAX)

As for the KERN_NGROUPS it is part of the BSD sysctl.h
header file.

Now you can’t blame me if you just go grepping headers
for values and take them out of context.

Pass me a piece of pie, will you?

Thanks,

  • igor

Igor Kovalenko <Igor.Kovalenko@motorola.com> wrote:
: Thomas Fletcher wrote:
:>
:> I’m at home right now but it looks like there might be a bug in
:> ‘id’ where it (Thomas begins to eat humble pie) looks like
:> it might expect the return value to include the group member
:> itself. Mmmmm mmm loving that pie!
:>
:> …

: I’d say the bug is not in ‘id’, it’s probably in initgroups() :wink:
: If you fix ‘id’ how do you know it won’t show up somewhere else?

No guarantee =;-) We have fixed the behaviour and can
all rejoice when it makes it into the future release/patch.
The fix will not be in the next RTP patch however.

Thomas

Thomas (toe-mah) Fletcher QNX Software Systems
thomasf@qnx.com Neutrino Development Group
(613)-591-0931 http://www.qnx.com/~thomasf