in reply to Retrieve unix group membership for a uid in a perl CGI

Given that you have the username, maybe you could just parse /etc/group.

The format is pretty simple:
name:x:group id (integeter):list,of,usernames

while (<GROUP>) { my ($group,$x,$gid,$list)=split(':',$_); push(@groups,$group) if ($list=~/$username/); }

Replies are listed 'Best First'.
Re: Re: Retrieve unix group membership for a uid in a perl CGI
by kvale (Monsignor) on Apr 09, 2004 at 18:18 UTC
    This misses the user's own group. Try
    my $username = "kvale"; my @groups = ($username); open GROUP, "</etc/group" or die "Could not find /etc/group: $!\n"; while (<GROUP>) { my ($group,$x,$gid,$list)=split(':',$_); push(@groups,$group) if ($list=~/$username/); } print "Groups: ", join " ", @groups, "\n";

    -Mark

      Actually yours (possibly mistakenly) assumes that the user's primary group is named after their username. While this is a common default value used by some variants of adduser or the like, it's not necessarily always the case. Which is of course why you should use getpwname to retrieve their primary gid and then translate that with getgrgid.

      Huh? I don't see any difference between my loop and yours...

      All you've done is provide the opening of the file, which I left as an exercise for the student

        Not true. I added the username to the @groups, which your parse misses. My /etc/group file looks something like
        kvale:x:501: cvs::502:kvale
        with no kvale user at the end of the kvale group. Note my solution is just a hack, because giving each user their own group is the default on my system.

        -Mark

Re: Re: Retrieve unix group membership for a uid in a perl CGI
by Fletch (Bishop) on Apr 09, 2004 at 18:24 UTC

    And then you move to a system running NIS or LDAP and miss anything not defined in the local /etc/group file. This is why you go through getgrent which uses the system's group reading libraries and honours nsswitch.conf (or whatever).

      I was going to use getgrent, for the guy's answer, and I couldn't get it to work.... Until now: I just realized that instead of looping through /etc/group, you can loop through getgrent.

      The thing I didn't immediately realize is that getgrent returns different values on subsequent calls.

      (Since I've never done this particular thing before, I was testing the code before posting...)